SpringBoot集成WebSocket实践

in 笔记 with 0 comment

1.添加SpringBoot对WebSocket的依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

2.添加配置

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

3.创建请求的接口

@Component
@ServerEndpoint("test/{parm}")
public class Test {

    // 用户在线数
    private static int onLineCount = 0;

    private static final Logger LOGGER = LoggerFactory.getLogger(Test.class);
    private Session session;

    private String sendUser;// 当前用户
    private String toUser;// 接收人
    private String message;// 聊天信息



    //实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key为用户标识

    private static Map<String,Test> connections = new ConcurrentHashMap<>();

    @OnMessage(maxMessageSize = 10)
    public void onMessage(String jsonString) throws IOException {
        System.out.println("来自客户端的消息"+jsonString);
        JSONObject json=JSONObject.parseObject(jsonString);
        sendUser = json.getString("sendUser");
        toUser = json.getString("toUser");
        message = json.getString("message");
        message = "来自:" + sendUser + "用户发给" + toUser + "用户的信息:" + message + " \r\n";

        LOGGER.info(message);
        Test user = connections.get(toUser);
        //如果接收人不存在则保持到数据库
        if (user == null) {
            System.out.println("信息持久化处理");
            return;
        }
        user.sendMessage("send",message);

    }
    @OnOpen
    public void onOpen(Session session, EndpointConfig endpointConfig, @PathParam("parm") String parm) throws IOException {
        this.session = session;
        //初始化用户
        this.sendUser = parm;
        LOGGER.info("新的连接,用户id={}",parm);
        addOnlineCount();
        System.out.println("有新连接加入!当前在线人数为" + getOnlineCount() + " 当前session是" + session.hashCode());
        connections.put(sendUser,this);
        for (Test chat : connections.values()) {
            //使用if判断是要统计人数还是发送消息
            chat.sendMessage("count",getOnlineCount() + "");
        }
    }
    @OnClose
    public void onClose(CloseReason closeReason) throws IOException {
        LOGGER.info("连接断开,id={} reason={}",this.session.getId(),closeReason);
        // 在线数减1
        subOnlineCount();
        for (Test chat : connections.values()) {
            if(chat.session != this.session){
                chat.sendMessage("count", getOnlineCount() + "");
            }
        }
        System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
    }
    @OnError
    public void onError(Throwable throwable) throws IOException {
        LOGGER.info("连接异常,id={},throwable={}",this.session.getId(),throwable);
        this.session.close();
        throwable.printStackTrace();
    }

    public void sendMessage(String type,String message) throws IOException {
        if("count".equals(type)){
            this.session.getBasicRemote().sendText("count:" + message);
        }else {
            this.session.getBasicRemote().sendText(message);
        }
    }

    // 获得当前在线人数
    public static synchronized int getOnlineCount() {
        return onLineCount;
    }
    public static synchronized void addOnlineCount() {
        Test.onLineCount++;
    }
    public static synchronized void subOnlineCount() {
        Test.onLineCount--;
    }
}

4.前端核心部分

var ws;
/**
 * 开始聊天
 */
var data = {
    sendUser:null,
    toUser:null,
    message:null
};

var inst = new mdui.Dialog('#single-chat', {
    modal: true
});

function show_signle_dialog() {
    var nick_name = $('#nick_name').val();
    console.log(nick_name)
    if (nick_name === '') {
        $('#nick_name').focus();
        mdui.snackbar({
            message: '请输入一个昵称'
        });
        return;
    }
    data.sendUser = nick_name;
    data.toUser = $("#to_user_nick_name").val();
    inst.open();
    $('#chat_addr').attr("value",'ws://192.168.43.29:8080/test/'+nick_name)

    new_websocket()
}

/**
 * 关闭聊天室
 */
function close_dialog() {
    $('#chat_msg').val('');
    mine_id = null, to_id = null;
    setTimeout(function () {
        $('.mdui-dialog-content .chat-body').html('<p class="mdui-m-b-3"><span class="chat-box-info"></span></p>');
    }, 180);
}

/**
 * 发送消息
 */
function send_msg() {
    var msg = $('#chat_msg').val();
    data.message = $('#chat_msg').val();
    var jsonString = JSON.stringify(data);
    console.log(jsonString)
    ws.send(jsonString);
    var html = '<p class="mdui-m-b-3"><span class="chat-box-pink">我 : '+ msg +'</span></p>';
    $('.mdui-dialog-content .chat-body').append(html);
    $('.mdui-dialog-content .chat-body').scrollTop($('.mdui-dialog-content .chat-body').height());
    $('#chat_msg').val('');
    $('#chat_msg').focus();
}

function new_websocket() {
    var chat_addr = $('#chat_addr').val();
    ws = new WebSocket(chat_addr);
    console.log(chat_addr)
    if(ws){

        ws.onopen = function () {
            // 使用 send() 方法发送数据
            console.log("连接成功")
        };

        // 接收聊天消息
        ws.onmessage = function(e){
            console.log("收到消息"+e.data);
            var html = '<p class="mdui-m-b-3"><span class="chat-box-green">' + e.data + '</span></p>';
            $('.mdui-dialog-content .chat-body').append(html);
            $('.mdui-dialog-content .chat-body').scrollTop($('.mdui-dialog-content .chat-body').height());
        };
    }
}
Responses