国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

JAVA使用WebSocket實現(xiàn)多客戶端請求

這篇具有很好參考價值的文章主要介紹了JAVA使用WebSocket實現(xiàn)多客戶端請求。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

工作前提:兩個服務(wù)之間實現(xiàn)聊天通訊,因為介于兩個服務(wù),兩個客戶端

方案1:多個服務(wù)端,多個客戶端,使用redis把用戶數(shù)據(jù)ip進(jìn)行存儲,交互拿到redis數(shù)據(jù)進(jìn)行推送

方案2: 一個服務(wù)端,多個客戶端,拿到客戶端的id和需要推送的id進(jìn)行拼接存儲

此文章使用的是方案2

1. 引入依賴包


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

2. 加入配置進(jìn)行掃描

ServerEndpointExporter 是由Spring官方提供的實現(xiàn),用于掃描@ServerEndpoint注解實例。

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

3. 服務(wù)端,這里主要是前端訪問地址:ws://ip:port/push/websocket/{{"fromUserId":"321654","toUserId":"123456"}},這個地址主要用于建立連接,會去主動調(diào)用onOpen方法,然后當(dāng)客戶端(前端)發(fā)送消息時,會主動調(diào)用onMessage方法,再進(jìn)行自己一列處理后,再推送給它需要發(fā)送的userId(用戶),就去調(diào)用senndMessage方法。

@Component
@ServerEndpoint("/push/websocket/{param}")
@Slf4j
@EqualsAndHashCode
public class WebSocketServer {
	 /**靜態(tài)變量,用來記錄當(dāng)前在線連接數(shù)。應(yīng)該把它設(shè)計成線程安全的。*/
    private static int onlineCount = 0;
    /**concurrent包的線程安全Set,用來存放每個客戶端對應(yīng)的WebSocket對象。*/
    private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
    /**與某個客戶端的連接會話,需要通過它來給客戶端發(fā)送數(shù)據(jù)*/
    private Session session;
    /**接收userId*/
    private String userId = "";

    @Autowired
    private InstantMessageService instantMessageService;

    /**
     * 連接建立成
     * 功調(diào)用的方法
     */
    @OnOpen
    public void onOpen(Session session,@PathParam("param") String param) {
        this.session = session;
        if (StringUtils.isNotBlank(param)) {
            JSONObject jsonObject = JSONObject.parseObject(param);
            log.info("發(fā)送者數(shù)據(jù):{},當(dāng)前在線人數(shù)為{}" ,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);
                //在線數(shù)加1
                addOnlineCount();
            }
            log.info("用戶連接:"+userId+",當(dāng)前在線人數(shù)為:" + getOnlineCount());
            sendMessage("連接成功");
        }
        log.info("未傳輸數(shù)據(jù)" + getOnlineCount());
    }

    /**
     * 連接關(guān)閉
     * 調(diào)用的方法
     */
    @OnClose
    public void onClose() {
        if(webSocketMap.containsKey(userId)){
            webSocketMap.remove(userId);
            //從set中刪除
            subOnlineCount();
        }
        log.info("用戶退出:"+userId+",當(dāng)前在線人數(shù)為:" + getOnlineCount());
    }

    /**
     * 收到客戶端消
     * 息后調(diào)用的方法
     * @param message
     * 客戶端發(fā)送過來的消息
     **/
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("用戶消息:"+this.userId+",報文:"+message);
        //可以群發(fā)消息
        //消息保存到數(shù)據(jù)庫、redis
        if(StringUtils.isNotBlank(message)){
            try {

                // 保存數(shù)據(jù)庫中,如果報錯則返回給發(fā)送者,成功推送給接收者
                ResponseBean responseBean = saveMessage(message);
                ErrorInfo errorInfo = responseBean.getErrorinfo();
                if (errorInfo != null) {
                    webSocketMap.get(this.userId).sendMessage(message);
                } else {
                    //解析發(fā)送的報文
                    //追加發(fā)送人(防止串改)
                    Map<String, Object> stringObjectMap = responseBean.getData();
                    if (stringObjectMap.containsKey("toUserId") && stringObjectMap.containsKey("fromUserId")) {

                        String userId=stringObjectMap.get("toUserId").toString()+"-"+stringObjectMap.get("fromUserId").toString();
                        //傳送給對應(yīng)toUserId用戶的websocket
                        if (webSocketMap.containsKey(userId)) {
                            webSocketMap.get(userId).sendMessage(message);
                        } else {
                            //否則不在這個服務(wù)器上,發(fā)送到mysql或者redis
                            log.error("請求的userId:"+userId+"不在該服務(wù)器上");
                        }
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     * 保存數(shù)據(jù)
     *
     * @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();
    }

    /**
     * 實現(xiàn)服務(wù)
     * 器主動推送
     */
    public void sendMessage(String message) {
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     *發(fā)送自定
     *義消息
     **/
    public static void sendInfo(RequestBean requestBean) {

        // 根據(jù)用戶id和企業(yè)id標(biāo)記已讀 修改狀態(tài)
        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("發(fā)送消息到:"+userId+",報文:"+map.toString());

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

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

    /**
     * 獲得此時的
     * 在線人數(shù)
     * @return
     */
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    /**
     * 在線人
     * 數(shù)加1
     */
    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }

    /**
     * 在線人
     * 數(shù)減1
     */
    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }

web端測試,這里傳給要發(fā)送的數(shù)據(jù)回去,傳輸接通

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

?網(wǎng)上有很多寫的很好的博主:這里有包含前后端

WebSocket實現(xiàn)前后端通訊-java_暮冰的博客-CSDN博客_websocket前后端?文章來源地址http://www.zghlxwxcb.cn/news/detail-511319.html

到了這里,關(guān)于JAVA使用WebSocket實現(xiàn)多客戶端請求的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包