Error during WebSocket handshake: Unexpected response code: 404,springboot整合websocket出错

浏览器访问websocket出现错误

一.运行环境

1.编译工具 idea
2.后台java,框架springboot
3.前端html

二、需要引入的包

		<!-- 引入thymeleaf-->
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- 引入websocket-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

三、项目路径

在这里插入图片描述

四、工具类

Websocket.java

package com.example.websocketdemo.util;

import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

/**
 * 1, WebSocket可以通过注解的方式声明  @ServerEndpoint("/WebSocket")
 * 2, 添加注解之后需要在配置文件中返回, 在配置文件中可以过滤
 * 3, WebSocket 和 Servlet 相同都是多列的, 不会互相干扰
 * 4, WebSocket 请求时访问 open  方法, 可以用注解 @OnOpen 标明
 * 5, WebSocket 关闭时访问 close 方法, 可以用注解 @OnClose 表名
 */
@Component
@ServerEndpoint("/WebSocket")
public class Websocket {
	public static Map<String,Session> onlineMap = new ConcurrentHashMap<>();
    @OnOpen
    public void open(Session session) {
    	String ip = WebsocketUtil.getRemoteAddress(session).getAddress().getHostAddress();
    	onlineMap.put(ip, session);
        System.out.println("通道 " + ip + " 打开");
    }
    
    @OnClose
    public void close(Session session) {
    	String ip = WebsocketUtil.getRemoteAddress(session).getAddress().getHostAddress();
    	onlineMap.remove(ip);
    	System.out.println("通道 " + ip + "关闭");
    }
    
    @OnMessage
    public void message(Session session, String msg) {
        String outMessade = "客户端 " + session.getId() + " 说:" + msg;
        System.out.println(outMessade);
        try {
            session.getBasicRemote().sendText(msg);
        } catch (IOException e) {
            System.out.println("返回数据失败");
        }
     }
}

Websocketutil

package com.example.websocketdemo.util;

import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import javax.websocket.RemoteEndpoint.Async;
import javax.websocket.Session;

public class WebsocketUtil {

	public static InetSocketAddress getRemoteAddress(Session session) {
		if (session == null) {
			return null;
		}
		Async async = session.getAsyncRemote();
		InetSocketAddress addr = (InetSocketAddress) getFieldInstance(async,
				"base#socketWrapper#socket#sc#remoteAddress");
		return addr;
	}

	private static Object getFieldInstance(Object obj, String fieldPath) {
		String fields[] = fieldPath.split("#");
		for (String field : fields) {
			obj = getField(obj, obj.getClass(), field);
			if (obj == null) {
				return null;
			}
		}

		return obj;
	}

	private static Object getField(Object obj, Class<?> clazz, String fieldName) {
		for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
			try {
				Field field;
				field = clazz.getDeclaredField(fieldName);
				field.setAccessible(true);
				return field.get(obj);
			} catch (Exception e) {
			}
		}
 
		return null;
	}
}

五、静态页面以及js

index2.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>TEMPLATES</title>
    <script type="text/javascript" src="../publicjs/jquery.min.js"></script>
    <script type="text/javascript" src="../js/index.js"></script>
</head>
<body>
<h1>首页2</h1>
<div id="div1"></div>
</body>
</html>

index.js

$(function(){
    console.log(11);
    $(document).ready(function(){
        window.websocket={};
        var userId='webPower';
        var api='你的IP';
        var app={
            /**
             *初始化socket,判断是否支持webSocket
             */
            initSocket:function () {
                if('WebSocket' in window)
                    websocket = new WebSocket("ws://"+document.location.host+"/WebSocket");
                app.state();
            },
            /**
             * 状态
             */
            state:function () {
                // 打开连接时
                websocket.onopen = function(evnt) {
                    console.log("websocket已启用");
                };

                // 收到消息时
                websocket.onmessage = function(evnt){
                    $(".layui-layer-content").html($(".layui-layer-content").html()+evnt.data);
                    //将websocket传到前端的内容写入到id为div1的div标签当中
                    $("#div1").append(evnt.data);
                };

                //出错时
                websocket.onerror = function(evnt) {
                    console.log("与后台握手出现问题!");
                };

                //关闭时
                websocket.onclose = function(evnt) {
                    console.log("正在关闭 webSocket");
                };
                //发送消息
                // websocket.send(msg);
            }
        };
        app.initSocket();
    });
})


6、测试代码

WebSocketController.java

package com.example.websocketdemo;

import com.example.websocketdemo.util.Websocket;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@Controller
public class WebSocketController {
    //接口调用,跳转到请求页面
    @RequestMapping("/index")
    @ResponseBody
    public String socketTest(HttpServletRequest req){
        try {
            Websocket.onlineMap.get(req.getRemoteAddr()).getBasicRemote().sendText("websocket测试");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "ceshi";
    }

    //跳转到templates目录下的html页面
    @RequestMapping("/aa")
    public String socketTest2(){
        return "index2";
    }
}

七、测试结果

浏览器出现:Error during WebSocket handshake: Unexpected response code: 404

八、原因分析

缺少WebSocket配置文件

九、解决办法

1.在util文件夹中添加一个WebSocketConfig.java文件

新的项目路径如下
在这里插入图片描述

10、新的测试结果

websocket正常访问
在这里插入图片描述
调用websocket输入前
在这里插入图片描述
调用websocket输入后效果

在这里插入图片描述

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页