WebSocket实现后台向前端推送信息

WebSocket实现后台向前端推送信息,第1张

WebSocket实现后台向前端推送信息 什么是WebSocket?

因为 HTTP 协议有一个缺陷:通信只能由客户端发起,HTTP 协议做不到服务器主动向客户端推送信息。
WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端

快速上手
 
        
            org.springframework.boot
            spring-boot-starter-websocket
        

WebSocketConfig启用WebSocket的支持

@Configuration
public class WebSocketConfig {

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

}

WebSocketServer
因为WebSocket是类似客户端服务端的形式(采用ws协议),那么这里的WebSocketServer其实就相当于一个ws协议的Controller

直接@ServerEndpoint("/imserver/{userId}") 、@Component启用即可,然后在里面实现@OnOpen开启连接,@onClose关闭连接,@onMessage接收消息等方法。

新建一个ConcurrentHashMap webSocketMap 用于接收当前userId的WebSocket,方便IM之间对userId进行推送消息。单机版实现到这里就可以。

集群版(多个ws节点)还需要借助mysql或者redis等进行处理,改造对应的sendMessage方法即可。

@ServerEndpoint("/imserver/{userId}")
@Component
public class WebSocketService {


    
    private static ConcurrentHashMap webSocketMap = new ConcurrentHashMap<>();
    
    private Session session;
    
    private String userId = "";

    
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        this.session = session;
        this.userId = userId;
        if (webSocketMap.containsKey(userId)) {
            webSocketMap.remove(userId);
            webSocketMap.put(userId, this);
            //加入set中
        } else {
            webSocketMap.put(userId, this);
            //加入set中
        }
        //服务端向客户端发送信息
        sendMessage("用户" + userId + "上线了,当前在线人数为:" + webSocketMap.size() + "。");
    }


    
    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    
    public void sendMessage(String message) {
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    
    public static void sendInfo(String message, String userId, String toUserId) {
        //log.info("发送消息到:"+userId+",报文:"+message);
        if (StringUtils.isNotBlank(toUserId) && webSocketMap.containsKey(toUserId)) {
            webSocketMap.get(toUserId).sendMessage(message);
        } else {
            webSocketMap.get(userId).sendMessage(toUserId + "已经下线。");
        }
    }

    
    public static void close(String userId) {
        if (webSocketMap.containsKey(userId)) {
            webSocketMap.remove(userId);
        }
    }

    
    public static Map getOnlineUser() {
        return webSocketMap;
    }

}

controller 对外提供发送 关闭websocket方法

@RestController
public class DemoController {



    @PostMapping("/push")
    public ResponseEntity pushToWeb(String message, String toUserId,String userId) throws IOException {
        WebSocketService.sendInfo(message,userId,toUserId);
        return ResponseEntity.ok("MSG SEND SUCCESS");
    }

    @GetMapping("/close")
    public String close(String userId){
        WebSocketService.close(userId);
        return "ok";
    }


    @GetMapping("/getOnlineUser")
    public Map getOnlineUser(){
        return WebSocketService.getOnlineUser();
    }

}

html 前端页面




    
    websocket通讯




【内容】:

【当前用户】:

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5697857.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存