java wrote a simple chat function

First of all, I was reading this chat room-> this blogger's article <-played the code with him again. If anyone sees the blog post I wrote, please go to this blogger to see the details. I just upload the code and make code notes.


After I read the blogger ’s blog, I probably think of the following ideas:

  • The first is to import dependencies, using a websocket function of HTML5:
<dependency>
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
  • Next is to add and configure WebSocketConfig.java
package com.example.java.webstock.demo.configWeb;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }
}

  • Then there is the Controller layer on the server side:

  • First make a simple test class
package com.example.java.webstock.demo.configServer;

import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
/*
* websocket其实很简单,前后端各写4个事件方法就行了(当然你也可以省略一些方法)
1.建立连接
2.收到消息
3.传输消息失败
4.关闭连接
* */
@Component
@ServerEndpoint("/websocket/{sid}")
public class WebSocketServerController {
//    收到消息调用方法
    @OnMessage
    public void onMessage(Session session, String message){
//        System.out.println("收到的消息为:"+message);
        try {
//       如果事件想和具体会话关联,方法上只要加Session参数就行(4种事件类型的方法上都可加)
//       举个例子,直接将用户发送给服务端的话再返回给客户端
            session.getBasicRemote().sendText(message);
        }catch (IOException e){
            e.printStackTrace();
        }
    }
//    建立连接调用方法
//    传递参数
//    方法上加@PathParam参数即可
    @OnOpen
    public void onOpen(@PathParam("sid") String sid){
        System.out.println("Client connected");
    }
//    关闭连接调用方法
    @OnClose
    public void onClose(){
        System.out.println("Connection closed");
    }
//    传输消息错误调用方法
    @OnError
    public void OnError(Throwable error){
        System.out.println("Connection error");
    }
}

  • This is the front-end code index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Testing websockets</title>
</head>
<body>
<div>
<!--
websocket其实很简单,前后端各写4个事件方法就行了
1.建立连接
2.收到消息
3.传输消息失败
4.关闭连接
-->
    <textarea rows="3" cols="20" id="content"></textarea>
    <br>
    <input type="submit" value="Start" onclick="start()" />
</div>
<div id="messages"></div>
<script type="text/javascript">
    var webSocket =
        new WebSocket('ws://localhost:8080/websocket/2020');

    webSocket.onerror = function(event) {
        onError(event)
    };

    webSocket.onopen = function(event) {
        onOpen(event)
    };

    webSocket.onmessage = function(event) {
        onMessage(event)
    };

    webSocket.onclose = function(event) {
        onClose(event)
    };


    function onMessage(event) {
        document.getElementById('messages').innerHTML
            += '<br />' + event.data;
    }

    function onOpen(event) {
        document.getElementById('messages').innerHTML
            = 'Connection established';
    }

    function onError(event) {
        alert(event);
    }

    function onClose(event) {
        alert(event);
    }

    function start() {
        var text = document.getElementById('content').value;
        webSocket.send(text);
    }
</script>
</body>
</html>

  • This is the test result:
    Insert picture description here

  • Then this is the function of realizing multiplayer online chat
  • GroupChatController.java
package com.example.java.webstock.demo.configServer;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
@ServerEndpoint("/groupChat/{sid}/{username}")
public class GroupChatController {
//    保存 组 ID -> 组成员 的映射关系
    private  static ConcurrentHashMap<String, List<Session>> groupMemberInfoMap = new ConcurrentHashMap<>();
//    接收到消息调用的方法 群成员发送消息
    @OnMessage
    public  void onMessage(@PathParam("sid") String sid,@PathParam("username") String username, String message ){
        List<Session> sessionList = groupMemberInfoMap.get(sid);
//        先一个群组内的成员发送消息
        sessionList.forEach(item ->{
            try{
                String text = username+" : "+ message;
                item.getBasicRemote().sendText(text);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }
    // 建立连接调用的方法,群成员加入
    @OnOpen
    public void onOpen(Session session, @PathParam("sid") String sid) {
        List<Session> sessionList = groupMemberInfoMap.get(sid);
        if (sessionList == null) {
            sessionList = new ArrayList<>();
            groupMemberInfoMap.put(sid,sessionList);
        }
        sessionList.add(session);
        log.info("Connection connected");
        log.info("sid: {}, sessionList size: {}", sid, sessionList.size());
    }

    // 关闭连接调用的方法,群成员退出
    @OnClose
    public void onClose(Session session, @PathParam("sid") String sid) {
        List<Session> sessionList = groupMemberInfoMap.get(sid);
        sessionList.remove(session);
        log.info("Connection closed");
        log.info("sid: {}, sessionList size: {}", sid, sessionList.size());
    }

    // 传输消息错误调用的方法
    @OnError
    public void OnError(Throwable error) {
        log.info("Connection error");
    }

}

  • I encountered a pit here. The blogger's slf4j import was not used in pom.xml. I went to the settings and imported lombok to solve it. This is a log.
  • Then index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Testing websockets</title>
</head>
<body>
<div>
    <input type="text" id="sid" placeholder="请输入房间"/><br>
    <input type="text" id="nickname" placeholder="请输入昵称"/><br>
    <input type="submit" value="连接" onclick="connect()" /><br>
    <textarea rows="3" cols="20" id="content"></textarea><br>
    <input type="submit" value="发送" onclick="start()" />
    <br>
</div>
<div id="messages"></div>
<script type="text/javascript">

    var webSocket = null;

    function onMessage(event) {
        document.getElementById('messages').innerHTML
            += '<br />' + event.data;
    }

    function onOpen(event) {
        document.getElementById('messages').innerHTML
            = 'Connection established';
    }

    function onError(event) {
        alert("发生错误");
    }

    function onClose(event) {
        alert("连接关闭");
    }

    function connect() {
        var sid = document.getElementById('sid').value;
        var nickname = document.getElementById('nickname').value;
        if (url == '' || nickname == '') {
            alert("房间号和用户名不能为空");
            return;
        }
        var serverHot =  window.location.host;
        // var url = 'ws://' + serverHot + '/groupChat/' + sid + '/' + nickname;
       var url = 'ws://localhost:8081/groupChat/' + sid + '/' + nickname;
        webSocket = new WebSocket(url);
        webSocket.onerror = function(event) {
            onError(event)
        };

        webSocket.onopen = function(event) {
            onOpen(event)
        };

        webSocket.onmessage = function(event) {
            onMessage(event)
        };

        webSocket.onclose = function(event) {
            onClose(event)
        };
    }

    function start() {
        var text = document.getElementById('content').value;
        webSocket.send(text);
        document.getElementById('content').value = '';
    }

</script>
</body>
</html>
  • This is the test result
    Insert picture description here

At the end, I basically wrote these codes intact. I experienced this fun and learned something myself. If you want to see more details, please click here to go to the original address to learn! I just made a note.

Published 20 original articles · praised 4 · visits 612

Guess you like

Origin blog.csdn.net/qq_45031575/article/details/105452223