WebSocket、整合springboot、一个聊天室demo

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

特点:它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。

在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

整合springboot + 一个群发消息、群组消息的demo

  1. 引入pom文件
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
  1. 启动类上加注解@EnableWebSocket
@EnableScheduling
@EnableWebSocket
@MapperScan(basePackages = "com.XX.dao")
@SpringBootApplication
public class Start {
    public static void main(String[] args) {
        SpringApplication.run(Start.class, args);
    }
}
  1. 在application.properties文件内修改端口号

    #server
    server.port=8002
    
  2. 建配置类WebSocketConfig

    @Configuration
    public class WebSocketConfig implements WebSocketConfigurer {
        @Autowired
        private MyMessageHandler handler;
        @Autowired
        private MyHandShakeInterceptor interceptor;
    
        @Override
        public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
            webSocketHandlerRegistry.addHandler(handler, "/WSSERVER").addInterceptors(interceptor).setAllowedOrigins("*");
        }
    }
    
  3. 写一个握手拦截器

    @Component
    public class MyHandShakeInterceptor implements HandshakeInterceptor {
        @Autowired
        private UserService userService;
    
        @Override
        public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
            ServletServerHttpRequest servletServerHttpRequest = (ServletServerHttpRequest) serverHttpRequest;
            HttpServletRequest req = servletServerHttpRequest.getServletRequest();
            User user = (User) req.getSession().getAttribute("user");
            map.put("user", userService.getUserMapper().selectByPrimaryKey(user.getId()));
            return true;
        }
    
        @Override
        public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
            //
        }
    }
    
  4. 写一个消息处理器

    @Component
    public class MyMessageHandler extends TextWebSocketHandler {
        //客户端列表
        private Map<String, WebSocketSession> clients = new ConcurrentHashMap<String, WebSocketSession>();
    
        public Map<String, WebSocketSession> getClients() {
            return clients;
        }
    
        @Override
        public void afterConnectionEstablished(WebSocketSession session) throws Exception {
            clients.put(session.getId(), session);
            System.out.println("建立连接:" + session.getId());
        }
    
        @Override
        public void handleMessage(WebSocketSession session, final WebSocketMessage<?> message) throws Exception {
            String p = message.getPayload().toString();
            User user = (User) session.getAttributes().get("user");
            System.out.println("收到消息:" + user.getAccount() + ":" + p);
            MyMsg myMsg = JSONObject.parseObject(p, MyMsg.class);
            myMsg.setCreatetime(new Date());
            myMsg.setSender(user.getAccount());
            //全体推送
            if (myMsg.getType().equals("all")) {
                myMsg.setReceiver("all");
                clients.entrySet().forEach(o -> {
                    try {
                        TextMessage textMessage = new TextMessage(JSON.toJSONString(myMsg));
                        o.getValue().sendMessage(textMessage);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
                //群组推送
            } else if (myMsg.getType().equals("grp")) {
                myMsg.setReceiver(user.getGrp());
                clients.entrySet().stream().filter(o -> {
                    User u = (User) o.getValue().getAttributes().get("user");
                    return u.getGrp().equals(myMsg.getReceiver());
                }).forEach(o -> {
                    try {
                        TextMessage textMessage = new TextMessage(JSON.toJSONString(myMsg));
                        o.getValue().sendMessage(textMessage);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
            }
        }
    
        @Override
        public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
            clients.remove(session.getId());
            System.out.println("断开连接:" + session.getId());
        }
    }
    
  5. 客户端页面

    <body class="bg-a">
    <div class="container-fluid h-100" id="app">
        <div class="row">
            <div class="col text-center bg-warning text-white shadow">websocket</div>
        </div>
        <div class="mt-2 h-75 border" id="chatbox" style="overflow: auto;">
            <div class="m-1" v-for="msg in msgs">
                <div>{{msg.sender}}->{{msg.receiver}}-{{msg.createtime|filterDate}}</div>
                <div>{{msg.content}}</div>
            </div>
        </div>
        <div class="form-inline mt-2">
            <select id="type" class="form-control form-control-sm">
                <option value="all">:全体</option>
                <option value="grp">:群组</option>
                <option value="prv">:用户</option>
            </select>
            <input id="msg" type="text" class="form-control form-control-sm ml-1"/>
            <button class="btn btn-sm btn-outline-success ml-1" onclick="sendMsg();">发送</button>
        </div>
    </div>
    <script th:inline="javascript">
        //ws
        var url = "ws://" + location.host + "/WSSERVER";
        var ws = new WebSocket(url);
    
        //app
        var app = new Vue({
            el: "#app",
            data: {msgs: []},
            filters: {
                filterDate: function (val) {
                    return $.msfmt.todate(val, true, 8);
                }
            }
        });
    
        //sendMsg
        function sendMsg() {
            var msg = {
                content: $("#msg").val(),
                type: $("#type").val()
            }
            ws.send(JSON.stringify(msg));
            layer.msg("发送成功");
            $("#msg").val("");
        }
    
        //ws-onmessage
        ws.onmessage = function (e) {
            app.msgs.push($.parseJSON(e.data));
        }
    </script>
    </body>
        
        
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值