Java WebSoket 用法实现

Java实现websocket的连接以及简易聊天室的后台服务实现

websocket可以类似长连接,建立好session连接后,可以实现服务端主动推送信息到客户端服务。

http连接是客户端发请求服务端返回数据,websocket可以实现服务端多次向客户端发送数据包。
pom.xml文件配置在基于`org.springframework.boot`:

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

配置WebSocketConfig中:
 

@Configuration
public class WebSocketConfig  {

    /**
     * 注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解声明的 websocket endpoint
     * @return
     */
    @Bean
    public  ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }
}

webSocket服务实现:

@ServerEndpoint(value = "/imServer/{username}") //类似于Controller中的路径
@Component
public class WebSocketServer {
    private  static final Logger logs = LoggerFactory.getLogger(WebSocketServer.class);

    public static  final Map<String,Session> sessionMap = new ConcurrentHashMap<>();


    /**
     * 创建链接
     * @param session
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("username") String username){
        sessionMap.put(username,session);
        logs.info("新用户加入username:{},当前人数:{}",username,sessionMap.size());
        JSONObject result = new JSONObject();
        JSONArray array = new JSONArray();
        result.put("users",array);
        for(Object key :sessionMap.keySet()){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("username",key);
            array.add(jsonObject);
        }
        sedAllMessage(JSONUtils.toJSONString(result));//把当前用户列表返给客户端

    }

    /**
     * 关闭连接
     * @param session
     * @param username 指定关闭哪一个session连接
     */
    @OnClose
    public void onClose(Session session, @PathParam("username") String username){
        sessionMap.remove(username);
        logs.info(username+"连接关闭成功");
    }

    /**
     * 消息中转站
     * 接收到客户端消息后调用此方法
     * @param message 客户端发来的消息
     * @param username 用户名
     */
    @OnMessage
    public void onMessage(String message, @PathParam("username") String username){
        logs.info("服务端收到用户{}的消息:{}",username,message);
        JSONObject parse = (JSONObject) JSONUtils.parse(message);
        String toUserName = parse.getString("to"); // 要发给谁
        String text = parse.getString("text");  // 发什么信息
        Session toSession = sessionMap.get(toUserName); // 找到对应用户的Session
        if(toSession != null){
            JSONObject json = new JSONObject();
            json.put("from",username);
            json.put("text",text);
            this.sendMessage(toSession,json.toJSONString());
            logs.info("发送到用户:{},消息:{}",toUserName,json.toJSONString());
        }else {
            logs.info("发送失败,未找到用户:{}的session连接",toUserName);
        }

    }

    @OnError
    public void onError(Throwable error){
        logs.error("webSocket 服务异常"+error.getMessage());
        error.printStackTrace();
    }

    /**
     * 把消息发给所有客户端
     * @param message
     */
    private void sedAllMessage(String message){
        try {
            for(Session session:sessionMap.values()){
                logs.info("服务端给客户端[{}]发送信息{}",session.getId(),message);
                session.getBasicRemote().sendText(message);
            }
        } catch (IOException e) {
            logs.error("服务端发送消息到客户端失败",e);
        }
    }

    /**
     * 向指定用户的session连接中发送消息
     * @param session 指定用户的session
     * @param message 消息文本
     */
    private void sendMessage(Session session,String message){
        try {
            session.getBasicRemote().sendText(message);//向客户端发送信息
        } catch (IOException e) {
            logs.error("服务端发送消息到客户端失败",e);
        }
    }

}

如果用到了SpringSecurity,则需要把服务路径添加到认证范围内。SecurityConfig

HTML页面js配置

webSocketInit(){
        if(typeof(WebSocket) == 'undefined'){
          console.log("您当前浏览器不支持websocket")
          return
        }
        //开启一个webSocket服务
        let ws = new WebSocket('ws://localhost:8082/imServer/aa')
        ws.onopen = function(){
          console.log("websocket服务建立连接")
          //ws.send('前端消息') // 发送信息
        };
        //onmessage 浏览器收消息,获得从服务端发来的文本消息
        ws.onmessage = function(event){
          console.log("接收到后端消息:"+event.data);
        }
        // 关闭
        ws.onclose = function(){
          console.log("websocket关闭连接")
        }
        //异常
        ws.onerror = function(event){
           console.log("异常信息"+event.data);
        }
      }

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值