分享

SpringBoot使用websocket实现简单聊天室

 印度阿三17 2021-02-23

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.">
<head>
    <meta charset="UTF-8">
    <title>网页聊天室</title>
    <style type="text/css">
        .chatdiv{width: 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;width: 100%}
        .othershuo{text-align: left;border-bottom: #ccc solid 1px;padding: 5px 0;color: dodgerblue;width: 100%}
        .xitongshuo{text-align: center;border-bottom: #ccc solid 1px;padding: 5px 0;color: red;font-weight: bold;width: 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./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>

测试效果截图:

来源:https://www./content-4-866851.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多