建立websocket连接并发送和处理数据

服务端

1、WebSocket配置类

在配置类中一般需要实现“注册WebSocket处理程序”、“Bean注册”。


@Configuration
@EnableWebSocket//启用WebSocket功能
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myWebSocketHandler(), "/chat")
                //将WebSocket处理程序注册到指定的路径
         .addInterceptors(new HandshakeInterceptor() {
            public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
                ServletServerHttpRequest request = (ServletServerHttpRequest)serverHttpRequest;
                String username = request.getServletRequest().getParameter("username");
                map.put("username", username);
                return true;
            }//从 HTTP 请求中获取用户名,并将其添加到 WebSocket 握手中的属性 Map 中
            
        });
    }

    @Bean
    public WebSocketHandler myWebSocketHandler() {
        return new MyWebSocketHandler();
        //创建了一个 WebSocket 处理程序的实例并将其作为 bean 注册到 Spring 上下文中。
        //这将使处理程序在需要时自动注入到其他组件中
    }


    }


 上面的代码首先注册了自定义的 WebSocket 处理程序。在自定义的WebSocket的处理程序中指定了客户端连接的路径;并添加了一个握手拦截器,用来获取HTTP请求的用户名,并将其添加到WebSocket握手中的Map属性中,以便WebSocketHandler 可以通过读取属性映射中的值来访问和使用这些信息。

其次创建了一个 WebSocket 处理程序的实例并将其作为 bean 注册到 Spring 上下文中

2、WebSocketHandler

在正式的处理逻辑中,一般需要实现"连接成功时的逻辑"、"连接失败时的逻辑"、“连接关闭的逻辑”。

public class MyWebSocketHandler implements WebSocketHandler {
    //保存所有在线用户的session的集合容器
    private static CopyOnWriteArrayList<WebSocketSession> sessions =
            new CopyOnWriteArrayList<>();
   //保存所有在线用户
    private static CopyOnWriteArrayList<String> usernames =
            new CopyOnWriteArrayList<>();
    ObjectMapper om = new ObjectMapper();//Java 对象和 JSON 数据之间进行序列化和反序列化。
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 连接成功时的逻辑
        //保存连接的这个人的session和用户名
        Map<String, Object> attributes = session.getAttributes();
        String username = (String) attributes.get("username");
        usernames.add(username);
        sessions.add(session);
        //发送一个谁谁谁上线了的消息给所有人
        Chat chat = new Chat(username,"上线了",1);
        String jsonStr = om.writeValueAsString(chat);
        //转发数据给所有人
        sendAll(jsonStr);
        //发送所有用户在线列表
        jsonStr = om.writeValueAsString(usernames);
        sendAll(jsonStr);

    }
    //向所有已连接websocket的客户端发消息
    private void sendAll(String jsonStr) throws IOException{
        for(WebSocketSession session: sessions){
            if(session.isOpen()){
                session.sendMessage(new TextMessage(jsonStr));
            }
        }
    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        // 处理消息的逻辑
        String username = (String) session.getAttributes().get("username");
        Chat msg = null;

        // 处理文本消息
        String msgStr = message.getPayload().toString();
        if("\0".equals(msgStr)){
            msg =new Chat(username,"发送了一个窗口抖动",5);
        }else if (msgStr.startsWith("\1")){
            String messageId = msgStr.substring(1);//从第一个位置开始截取,第0个位置是\1
            msg = new Chat(username,"撤回了一条消息",6,messageId);
        }else{
            String msgT = msgStr.substring(1);
            msg = new Chat(username,msgT,4, UUID.randomUUID().toString());
            System.out.println("文本消息");
            System.out.println(msgT);
        }
    
        String jsonStr = om.writeValueAsString(msg);
        sendAll(jsonStr);
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        // 处理连接失败时的逻辑
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        // 连接关闭时的逻辑
        String username = (String) session.getAttributes().get("username");
        //移除这个session
        sessions.remove(session);
        usernames.remove(username);
        Chat message = new Chat("系统消息",username+"下线了",1);
        String jsonStr = om.writeValueAsString(message);
        sendAll(jsonStr);
        jsonStr = om.writeValueAsString(usernames);
        sendAll(jsonStr);
    }

}

上面的代码中:

1)连接成功的逻辑;首先保存了连接WebSocket服务器客户端的session以及用户名;然后将用户上线消息广播到了连接这个WebSocket服务器的所有客户端;并且刷新群聊用户在线用户列表。

其次定义了客户端如何与WebSocket交互的逻辑,识别传输消息的第一个字符,做出相应包装处理,广播给所有客户端

2)连接失败的逻辑;未定义

3)连接关闭的逻辑;移除客户端session以及将用户名从用户列表中删除并发送下线消息。

另外将消息广播到所有连接客户端的逻辑独立出来复用

前端

在js代码中,同样应该首先向WebSocket服务器建立逻辑,然后再定义“连接成功的逻辑”、“连接失败的逻辑”、“连接关闭的逻辑”。

var username = $("#username").val();
//window.location.host代表获取ip:port
var url = "ws://" + window.location.host + "/chat?username=" + username;
//与后台建立websocket长连接
// alert(url);
var  ws = new WebSocket(url);
ws.onopen = function () {
    //处理成功时的逻辑
    console.log("成功")
};
ws.onmessage = function (e) {
//处理消息的逻辑
    var message = JSON.parse(e.data);
    console.log("成功+1")
    //alert(message.type);
    //alert(message.content);
    if (!message.type){
        onlineUser(message);
    }else if (message.type == 1) {
        //系统上线消息
        systemOnlineMessage(message);
    }else if(message.type == 4){
        //用户文本消息
        userTextMessage(message);
    }else if(message.type == 5){
        //    收到用户抖动消息
        dydMessage(message);
    }else if(message.type == 6){
        //用户撤销消息
        withdrawMessage(message);
    }else if(message.type == 7){
        userImageMessage(message);
    }
    ws.onclose = function(event) {
        // 连接关闭时的逻辑
    }
    /*滚动条滑到最底部*/
    $("#record").scrollTop(9999999);
};

具体函数实现代码未给出,代码使了的jquery库

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值