springBoot整合WebSocket实现的聊天室demo,可向指定客户端发送消息

 

 

直接上代码

首先加入依赖


	org.springframework.boot
	spring-boot-starter-freemarker


	org.springframework.boot
	spring-boot-starter-websocket

 

 

然后将此类注入到spring容器中:

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();
    }

}

建立连接,关闭连接,发送消息 主要代码如下:

/**
 * Copyright [2016-2017] [yadong.zhang]
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.yudi.websocket;

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;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 */
@ServerEndpoint(value = "/websocket/{userId}")
@Component
public class MyWebSocket {
    /**
     * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
     */
   // private static CopyOnWriteArraySet webSocketSet = new CopyOnWriteArraySet();
    /**3
     * 为了区分不同的客户端改用ConcurrentHashMap,每次客户端建立一个连接,就会存入一条记录,key为客户端的userId,value为socket连接实例
     * 这样可以通过 userId来调用其指定的连接进行操作。
     */
    private static ConcurrentHashMap webSocketMap = new ConcurrentHashMap();

    /**
     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    private Session session;

    /**
     * 群发自定义消息
     */
    public static void sendInfo(String message) {
        webSocketMap.forEach((k,v)->{
            try {
                v.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }

        });
    }
    /**
     * 向指定userId发送消息
     */
    public static void sendInfo(String userId,String message) {
        webSocketMap.forEach((k,v)->{
            try {
                if (k.equals(userId)){
                    v.sendMessage(message);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        });
    }
    /**
     * 连接建立成功调用的方法
     *
     */
    @OnOpen
    public void onOpen(@PathParam("userId")String userId, Session session) {
        System.out.println(userId);
        this.session = session;
        webSocketMap.put(userId,this);
        List list = new ArrayList();
        webSocketMap.forEach((k,v)->list.add(k));
//        addOnlineCount();
        System.out.println("有新连接加入!当前在线人数为" + webSocketMap.size());
        sendInfo("当前共有" + webSocketMap.size() + " 位用户在线,userId是:" +list.toString());

    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam("userId")String userId) {
        webSocketMap.remove(userId);
        sendInfo("当前共有" + webSocketMap.size() + " 位用户在线");
        System.out.println("有一连接关闭!当前在线人数为" + webSocketMap.size());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message
     *         客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("来自客户端的消息:" + message);

        //群发消息
        sendInfo(message);
    }
    /**
     * 发生错误时调用
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }

    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }
}

配置文件添加freemarker相关配置:

freemarker:
      allow-request-override: false
      allow-session-override: false
      cache: false
      charset: UTF-8
      check-template-location: true
      content-type : text/html
      enabled : true
      expose-request-attributes : false
      expose-session-attributes: false
      expose-spring-macro-helpers: true
      prefer-file-system-access: true
      suffix: .ftl
      template-loader-path: classpath:/templates/
      order: 1
      settings:
        template_update_delay: 0
        default_encoding: UTF-8
        classic_compatible: true

客户端代码:




    WebSocket测试 | 聊天小程序
    
    
    
    



    测试用controller:

    package com.yudi.websocket.controller;
    import com.yudi.websocket.MyWebSocket;
    import org.apache.commons.lang.StringUtils;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.MediaType;
    import org.springframework.http.ResponseEntity;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    @Controller
    @RequestMapping("/websocket")
    public class WebSocketController {
        /**
         * 给所有人发消息/指定userId发送消息
         * @param message
         * @return
         */
        @ResponseBody
        @RequestMapping(value = "/sendMessage", method = RequestMethod.GET)
        public ResponseEntity sendMessage(String userId,String message) {
            if (StringUtils.isEmpty(userId)){
                //向全部人发送消息
                MyWebSocket.sendInfo(message);
            }else {
                //向指定userId发送消息
                MyWebSocket.sendInfo(userId,message);
            }
    
    
            return new ResponseEntity(null,HttpStatus.OK);
        }
    
    
        /**
         * 登入聊天室
         * @param userId 用户id,每个人唯一,每一个userId会建立一个websocket连接
         * @param request
         * @param response
         * @return
         */
        @RequestMapping("/index")
        public String index(String userId, HttpServletRequest request, HttpServletResponse response) {
            request.setAttribute("userId",userId);
            return "index";
        }
    }
    

    效果图:

    springBoot整合WebSocket实现的聊天室demo,可向指定客户端发送消息_第1张图片

    向指定userId发送消息:http://localhost:8100/websocket/sendMessage?message=xxxx&userId=2 

    你可能感兴趣的:(springBoot整合WebSocket实现的聊天室demo,可向指定客户端发送消息)