• SpringBoot使用websocket实现简单聊天室


    1.实现代码

    <dependency>
       <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    
    @Configuration
    public class WebsocketConfig {
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
            return new ServerEndpointExporter();
        }
    }
    
    @Slf4j
    @Component
    @ServerEndpoint(value = "/ws/chat")
    public class ChatSocketServer {
    
        public static final AtomicInteger onlineCount = new AtomicInteger(0);
        public static Map<String, Session> clients = new ConcurrentHashMap<>();
    
        /**
         * 连接建立成功调用的方法
         */
        @OnOpen
        public void onOpen(Session session) {
            String username=session.getRequestParameterMap().get("username").get(0);
            log.info("有新的客户端上线 sessionid={} username={}", session.getId(),username);
            clients.put(username,session);
            int cnt = onlineCount.incrementAndGet(); // 在线数加1
            log.info("有连接加入,当前在线人数为:{}", cnt);
        }
    
        /**
         * 连接关闭调用的方法
         */
        @OnClose
        public void onClose(Session session) {
            clients.remove(session);
            int cnt = onlineCount.decrementAndGet();
            log.info("在线人数为:{}", cnt);
        }
    
        /**
         * 出现错误
         */
        @OnError
        public void onError(Session session, Throwable error) {
            log.error("发生错误:{},Session ID: {}",error.getMessage(),session.getId());
            error.printStackTrace();
        }
    
        /**
         * 收到客户端消息后调用的方法
         * @param message 客户端发送过来的消息
         */
        @OnMessage
        public void onMessage(String message, Session session) {
            log.info("消息:{}",message);
            //SendMessage(session, "收到消息,消息内容:"+message);
        }
    
        /**
         * 发送消息,username为空就群发
         */
        public static void SendMessage(Message message) throws IOException {
            //username为空就群发
            if(StringUtils.isBlank(message.getTo())){
                for (Map.Entry<String,Session> entry: clients.entrySet()) {
                    Session session=entry.getValue();
                    if(session.isOpen()){
                        session.getBasicRemote().sendText(JSON.toJSONString(message));
                    }
                }
            }else{
                for (Map.Entry<String,Session> entry: clients.entrySet()) {
                    if(entry.getKey().equals(message.getTo())){
                        Session session=entry.getValue();
                        if(session!=null && session.isOpen()){
                            session.getBasicRemote().sendText(JSON.toJSONString(message));
                        }else{
                            log.warn("没有找到你指定用户:{}",message.getTo());
                        }
                        break;
                    }
                }
            }
        }
    
    }
    
    @Controller
    public class ChatController {
    
    	@GetMapping("/")
    	public String index(){
    		return "chat";
    	}
    
    	@GetMapping("/chat/send")
    	@ResponseBody
    	public AjaxResult send(String from,String to,String message) throws IOException {
    		ChatSocketServer.SendMessage(new Message(from,to,message,new Date()));
    		return AjaxResult.success();
    	}
    
    	//在线用户列表
    	@GetMapping("/getOnlineUser")
    	@ResponseBody
    	public AjaxResult getOnlineUser() {
    		return AjaxResult.success(ChatSocketServer.clients.keySet());
    	}
    }
    
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public class Message {
        private String from;
        private String to;
        private String message;
        private Date time;
    }
    
    <!DOCTYPE html>
    <html lang="zh" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>网页聊天室</title>
        <style type="text/css">
            .chatdiv{ 800px;height: 300px;padding: 10px;margin: 10px;border: #444 solid 1px;}
            .myshuo{text-align: right;border-bottom: #ccc solid 1px;padding: 5px 0;color: green; 100%}
            .othershuo{text-align: left;border-bottom: #ccc solid 1px;padding: 5px 0;color: dodgerblue; 100%}
            .xitongshuo{text-align: center;border-bottom: #ccc solid 1px;padding: 5px 0;color: red;font-weight: bold; 100%}
        </style>
    </head>
    <body>
    
    <div id="loginpage" style="display: block">
        <h3>用户登陆</h3>
        输入用户名:<input type="text" id="username"><input type="button" onclick="login()" value="登陆">
    </div>
    
    <div id="chatpage" style="display: none">
        <div class="chatdiv" id="chatdiv"></div>
        <div>
            <select id="to" multiple="multiple" size="5">
            </select>
            <input type="button" onclick="getOnlineUser()" value="刷新当前在线用户">
            <input type="text" id="text"><input type="button" onclick="sendMessage()" value="发送">
        </div>
    </div>
    
    
    <script src="http://apps.bdimg.com/libs/jquery/1.11.3/jquery.min.js"></script>
    <script type="text/javascript">
        var socket;
        var myusername="";
    
        function getOnlineUser(){
            $.get("/getOnlineUser",{},function(result){
                $("#to").empty();
                $("#to").append($("<option>").val("").text("全部"));
                for(var i=0;i<result.data.length;i++){
                    $("#to").append($("<option>").val(result.data[i]).text(result.data[i]));
                }
            },'json');
        }
    
        function sendMessage(){
            var text=$("#text").val();
            if(text==''){
                alert('消息内容不能为空');
                return;
            }
            var to=$("#to").val()[0];
            if(to!=''){
                $("#chatdiv").append("<div class='myshuo'>我说:"+text+"</div>");
            }
            $.get("/chat/send",{from:myusername,to:to,message:text},function(result){
                console.info(result);
                $("#text").val("");
            },'json');
        }
    
        function login(){
            var username=$("#username").val();
            if(username==''){
                alert('用户不能为空');
                return;
            }
            myusername=username;
    
            if (typeof (WebSocket) == "undefined") {
                console.log("遗憾:您的浏览器不支持WebSocket");
            } else {
                console.log("恭喜:您的浏览器支持WebSocket");
                //实现化WebSocket对象
                //指定要连接的服务器地址与端口建立连接
                //注意ws、wss使用不同的端口。我使用自签名的证书测试,无法使用wss,浏览器打开WebSocket时报错
                //ws对应http、wss对应https。
                socket = new WebSocket("ws://localhost:8082/ws/chat?username="+username);
                //连接打开事件
                socket.onopen = function() {
                    console.log("Socket 已打开");
                    //socket.send("消息发送测试(From Client)");
                    $("#loginpage").hide();
                    $("#chatpage").show();
                    getOnlineUser();
                };
                //收到消息事件
                socket.onmessage = function(msg) {
                    console.log(msg.data);
                    var message=JSON.parse(msg.data);
                    if(message.to==''){
                        $("#chatdiv").append("<div class='xitongshuo'>【管理员】"+message.from+"说:"+message.message+"</div>");
                    }else{
                        $("#chatdiv").append("<div class='othershuo'>"+message.from+"说:"+message.message+"</div>");
                    }
    
                };
                //连接关闭事件
                socket.onclose = function() {
                    console.log("Socket已关闭");
                };
                //发生了错误事件
                socket.onerror = function() {
                    alert("Socket发生了错误");
                }
                //窗口关闭时,关闭连接
                window.unload=function() {
                    socket.close();
                };
            }
        }
    
    </script>
    </body>
    </html>
    

    测试效果截图:

  • 相关阅读:
    Windows Server 2019 Core 或 hyper-v server 2019图形工具安装
    添加进站允许规则和出站规则命令 netsh advfirewall firewall
    ID 1196 请确保与从属 IP 地址相关联的网络适配器已配置为至少可以访问一个 DNS 服务器
    通过注册表的方式禁用IPV6
    MS-SQL SERVER服务器占用CPU高,用语句先排查。
    hyper-v server 卸载软件(MD-DOS卸载软件)
    除getopenFilename以外。打开文件的另一种方式FileDialog
    返回当前工作簿的目录ThisWorkbook.path & ""
    筛选
    自动填充
  • 原文地址:https://www.cnblogs.com/daikainan/p/14433904.html
Copyright © 2020-2023  润新知