springboot集成WebSocket遇到的问题

springboot集成WebSocket遇到的问题

  1. 报错信息
    在这里插入图片描述
    (1)出现这个问题,首先检查一下路径是否正确
    (2)查看注解@ServerEndpoint 是否起作用,若是没起作用,就是项目启动时,没有注入
    (3)查看websocketConfig配置类,查看注解是否起作用,我在该配置类用的注解@Configuration 就是不起作用,后来改为了@Configurable 这个注解才可以
    2. 代码附上
    (1)java
	1. 引入依赖
	
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-websocket</artifactId>
			<version>2.0.9.RELEASE</version>
		</dependency>
	
	
	2. 配置类
	
		import org.springframework.beans.factory.annotation.Configurable;
		import org.springframework.context.annotation.Bean;
		import org.springframework.web.socket.server.standard.ServerEndpointExporter;

		/**
		 * WebSocketConfig
		 */
		@Configurable
		public class WebSocketConfig {
		
			@Bean
			public ServerEndpointExporter serverEndpoint() {
				return new ServerEndpointExporter();
			}
		}
	

	3.  websocket
	
		import org.springframework.stereotype.Component;
		import javax.websocket.OnClose;
		import javax.websocket.OnMessage;
		import javax.websocket.OnOpen;
		import javax.websocket.Session;
		import javax.websocket.server.PathParam;
		import javax.websocket.server.ServerEndpoint;
		import java.util.HashSet;
		import java.util.Map;
		import java.util.Set;
		import java.util.concurrent.ConcurrentHashMap;
		
		/**
		 * Created with IntelliJ IDEA.
		 *
		 * @Author: Administrator
		 * @Date: 2022/06/28/16:41
		 * @Description:
		 */
		@ServerEndpoint("/webSocket/chat/{roomName}")
		@Component
		public class WsServer {
		
		    // 使用map来收集session,key为roomName,value为同一个房间的用户集合
		    // concurrentMap的key不存在时报错,不是返回null
		    private static final Map<String, Set<Session>> rooms = new ConcurrentHashMap();
		
		    @OnOpen
		    public void connect(@PathParam("roomName") String roomName, Session session) throws Exception {
		        // 将session按照房间名来存储,将各个房间的用户隔离
		        if (!rooms.containsKey(roomName)) {
		            // 创建房间不存在时,创建房间
		            Set<Session> room = new HashSet<>();
		            // 添加用户
		            room.add(session);
		            rooms.put(roomName, room);
		        } else {
		            // 房间已存在,直接添加用户到相应的房间
		            rooms.get(roomName).add(session);
		        }
		    }
		
		    @OnClose
		    public void disConnect(@PathParam("roomName") String roomName, Session session) {
		        rooms.get(roomName).remove(session);
		    }
		
		    @OnMessage
		    public void receiveMsg(@PathParam("roomName") String roomName,
		                           String msg, Session session) throws Exception {
		        // 此处应该有html过滤
		        msg = session.getId() + ":" + msg;
		        // 接收到信息后进行广播
		        broadcast(roomName, msg);
		    }
		
		    // 按照房间名进行广播
		    public static void broadcast(String roomName, String msg) throws Exception {
		        for (Session session : rooms.get(roomName)) {
		            session.getBasicRemote().sendText(msg);
		        }
		    }
		}
(2)前端代码
		<!DOCTYPE html><html lang="en">
		<head>
		    <meta charset="UTF-8">
		    <title>网络聊天室</title>
		</head>
		<style type="text/css">
		    .msg_board {
		        width: 322px;
		        height: 100px;
		        border: solid 1px darkcyan;
		        padding: 5px;
		        overflow-y: scroll;
		    // 文字长度大于div宽度时换行显示
		    word-break: break-all;
		    }
		    /*set srcoll start*/
		    ::-webkit-scrollbar
		    {
		        width: 10px;
		        height: 10px;
		        background-color: #D6F2FD;
		    }
		    ::-webkit-scrollbar-track
		    {
		        -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
		        /*border-radius: 5px;*/
		        background-color: #D6F2FD;
		    }
		    ::-webkit-scrollbar-thumb
		    {
		        height: 20px;
		        /*border-radius: 10px;*/
		        -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
		        background-color: #89D7F7;
		    }
		    /*set srcoll end*/
		</style>
		<body>
		<label>房间名</label>
		<input id="input_roomName" size="10" maxlength="10">
		<input type="button"  value="进入聊天室" onclick="initWebSocket()" />
		<input type="button" value="退出聊天室" onclick="closeWs()" /><br>
		<div class="msg_board"></div>
		<input id="input_msg" size="43" maxlength="40">
		<input type="button" value="发送" onclick="send_msg()" />
		</body>
		<script type="text/javascript">
		    var webSocket;
		
		    function send_msg() {
		        if (webSocket != null) {
		            var input_msg = document.getElementById("input_msg").value.trim();
		            if (input_msg == "") {
		                return;
		            }
		            webSocket.send(input_msg);
		            // 清除input框里的信息
		            document.getElementById("input_msg").value = "";
		        } else {
		            alert("您已掉线,请重新进入聊天室...");
		        }
		    };
		
		    function closeWs() {
		        webSocket.close();
		    };
		
		    function initWebSocket() {
		        var roomName = document.getElementById("input_roomName").value;
		        // 房间名不能为空
		        if (roomName == null || roomName == "") {
		            alert("请输入房间名");
		            return;
		        }
		        if ("WebSocket" in window) {
		//            alert("您的浏览器支持 WebSocket!");
		            if (webSocket == null) {
		                var url = "http://localhost:8083/webSocket/chat/" + roomName;
		                url=url.replace("https","ws").replace("http","ws");
		                alert("url====="+url);
		                // 打开一个 web socket
		                webSocket = new WebSocket(url);
		            } else {
		                alert("您已进入聊天室...");
		            }
		            webSocket.onopen = function () {
		                alert("已进入聊天室,畅聊吧...");
		            };
		
		            webSocket.onmessage = function (evt) {
		                console.log("链接拿时空裂缝你的卡夫卡")
		                var msg_board = document.getElementsByClassName("msg_board")[0];
		                var received_msg = evt.data;
		                var old_msg = msg_board.innerHTML;
		                msg_board.innerHTML = old_msg + received_msg + "<br>";
		                // 让滚动块往下移动
		                msg_board.scrollTop = msg_board.scrollTop + 40;
		            };
		            webSocket.onclose = function (e) {
		                // 关闭 websocket,清空信息板
		                console.log('websocket 断开: ' + e.code + ' ' + e.reason + ' ' + e.wasClean)
		                console.log(e)
		                alert("连接已关闭...");
		                webSocket = null;
		                document.getElementsByClassName("msg_board")[0].innerHTML = "";
		            };
		        }
		        else {
		            // 浏览器不支持 WebSocket
		            alert("您的浏览器不支持 WebSocket!");
		        }
		    }
		</script>
		</html>
  1. 部署问题
    若用nginx部署,需要添加代码:
		location /webSocket/chat {
			 proxy_pass  http://localhost:8083/webSocket/chat;
             proxy_set_header Host $host;
             proxy_set_header Upgrade 'websocket';
             proxy_set_header Connection 'Upgrade';
			 proxy_connect_timeout 4s;
			 proxy_read_timeout 7200s; #两个小时
			 proxy_send_timeout 12s;
		}

proxy_read_timeout这个设置是websocket在短时间内没有回应的话,会自动断开,可以设置该值设置websocket短时间内不断开,这个时间是从最后一次发消息后开始计算,若当中有发送消息,则会重新计算时间

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值