JAVA使用WebSocket实现多客户端请求

这篇具有很好参考价值的文章主要介绍了JAVA使用WebSocket实现多客户端请求。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

工作前提:两个服务之间实现聊天通讯,因为介于两个服务,两个客户端

方案1:多个服务端,多个客户端,使用redis把用户数据ip进行存储,交互拿到redis数据进行推送

方案2: 一个服务端,多个客户端,拿到客户端的id和需要推送的id进行拼接存储

此文章使用的是方案2

1. 引入依赖包


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

2. 加入配置进行扫描

ServerEndpointExporter 是由Spring官方提供的实现,用于扫描@ServerEndpoint注解实例。

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

3. 服务端,这里主要是前端访问地址:ws://ip:port/push/websocket/{{"fromUserId":"321654","toUserId":"123456"}},这个地址主要用于建立连接,会去主动调用onOpen方法,然后当客户端(前端)发送消息时,会主动调用onMessage方法,再进行自己一列处理后,再推送给它需要发送的userId(用户),就去调用senndMessage方法。

@Component
@ServerEndpoint("/push/websocket/{param}")
@Slf4j
@EqualsAndHashCode
public class WebSocketServer {
	 /**静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。*/
    private static int onlineCount = 0;
    /**concurrent包的线程安全Set,用来存放每个客户端对应的WebSocket对象。*/
    private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
    /**与某个客户端的连接会话,需要通过它来给客户端发送数据*/
    private Session session;
    /**接收userId*/
    private String userId = "";

    @Autowired
    private InstantMessageService instantMessageService;

    /**
     * 连接建立成
     * 功调用的方法
     */
    @OnOpen
    public void onOpen(Session session,@PathParam("param") String param) {
        this.session = session;
        if (StringUtils.isNotBlank(param)) {
            JSONObject jsonObject = JSONObject.parseObject(param);
            log.info("发送者数据:{},当前在线人数为{}" ,param ,getOnlineCount());

            String userId = jsonObject.getString("fromUserId")+"-"+jsonObject.getString("toUserId");
            this.userId=userId;
            if(webSocketMap.containsKey(userId)){
                webSocketMap.remove(userId);
                //加入set中
                webSocketMap.put(userId,this);
            }else{
                //加入set中
                webSocketMap.put(userId,this);
                //在线数加1
                addOnlineCount();
            }
            log.info("用户连接:"+userId+",当前在线人数为:" + getOnlineCount());
            sendMessage("连接成功");
        }
        log.info("未传输数据" + getOnlineCount());
    }

    /**
     * 连接关闭
     * 调用的方法
     */
    @OnClose
    public void onClose() {
        if(webSocketMap.containsKey(userId)){
            webSocketMap.remove(userId);
            //从set中删除
            subOnlineCount();
        }
        log.info("用户退出:"+userId+",当前在线人数为:" + getOnlineCount());
    }

    /**
     * 收到客户端消
     * 息后调用的方法
     * @param message
     * 客户端发送过来的消息
     **/
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("用户消息:"+this.userId+",报文:"+message);
        //可以群发消息
        //消息保存到数据库、redis
        if(StringUtils.isNotBlank(message)){
            try {

                // 保存数据库中,如果报错则返回给发送者,成功推送给接收者
                ResponseBean responseBean = saveMessage(message);
                ErrorInfo errorInfo = responseBean.getErrorinfo();
                if (errorInfo != null) {
                    webSocketMap.get(this.userId).sendMessage(message);
                } else {
                    //解析发送的报文
                    //追加发送人(防止串改)
                    Map<String, Object> stringObjectMap = responseBean.getData();
                    if (stringObjectMap.containsKey("toUserId") && stringObjectMap.containsKey("fromUserId")) {

                        String userId=stringObjectMap.get("toUserId").toString()+"-"+stringObjectMap.get("fromUserId").toString();
                        //传送给对应toUserId用户的websocket
                        if (webSocketMap.containsKey(userId)) {
                            webSocketMap.get(userId).sendMessage(message);
                        } else {
                            //否则不在这个服务器上,发送到mysql或者redis
                            log.error("请求的userId:"+userId+"不在该服务器上");
                        }
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     * 保存数据
     *
     * @param message
     * @return
     */
    private ResponseBean saveMessage(String message) {

        RequestBean requestBean = JSONObject.parseObject(message,RequestBean.class);

        return instantMessageService.addChat(requestBean);
    }


    /**
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("用户错误:"+this.userId+",原因:"+error.getMessage());
        error.printStackTrace();
    }

    /**
     * 实现服务
     * 器主动推送
     */
    public void sendMessage(String message) {
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     *发送自定
     *义消息
     **/
    public static void sendInfo(RequestBean requestBean) {

        // 根据用户id和企业id标记已读 修改状态
        Map<String, Object> map = requestBean.getData();
        if (MapUtil.isNotEmpty(map)) {
            // 处理已读
            String fromUserId = map.get("fromUserId").toString();
            String toUserId = map.get("toUserId").toString();
            String userId = toUserId+"-"+fromUserId;
            log.info("发送消息到:"+userId+",报文:"+map.toString());

            if(StringUtils.isNotBlank(userId) && webSocketMap.containsKey(userId)){

                webSocketMap.get(userId).sendMessage(map.toString());
            }else{
                log.error("用户"+userId+",不在线!");
            }
        }
    }

    /**
     * 获得此时的
     * 在线人数
     * @return
     */
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    /**
     * 在线人
     * 数加1
     */
    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }

    /**
     * 在线人
     * 数减1
     */
    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }

web端测试,这里传给要发送的数据回去,传输接通

    @RequestMapping("socket")
    public void socket(@RequestBody RequestBean requestBean) {
        try {
            WebSocketServer.sendInfo(requestBean);
        } catch (Exception e) {
            logger.error("socket处理失败", e);
        }
    }

 网上有很多写的很好的博主:这里有包含前后端

WebSocket实现前后端通讯-java_暮冰的博客-CSDN博客_websocket前后端 文章来源地址https://www.toymoban.com/news/detail-511319.html

到了这里,关于JAVA使用WebSocket实现多客户端请求的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包