[WebSocket]浣跨敤WebSocket瀹炵幇瀹炴椂澶氫汉绛旈瀵规垬娓告垙

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[WebSocket]浣跨敤WebSocket瀹炵幇瀹炴椂澶氫汉绛旈瀵规垬娓告垙相关的知识,希望对你有一定的参考价值。

鏍囩锛?a href='http://www.mamicode.com/so/1/%e7%9f%a5%e8%af%86%e7%82%b9' title='鐭ヨ瘑鐐?>鐭ヨ瘑鐐?/a>   鐢ㄦ埛鍒涘缓   apache   浼樺寲   return   鍗忚   sessionid   甯姪   

鎶€鏈浘鐗? src=

鍓嶈█

鍓嶄袱绔犳暀绋嬶紝鎴戜滑浣跨敤WebSocket鐨勫熀纭€鐗规€ф墦閫犱簡涓€涓皬灏忚亰澶╁锛屽苟鍦ㄧ浜岀珷瀵瑰叾杩涜浜嗛泦缇ゅ寲鏀归€犮€?/p>

绯诲垪鏁欑▼鍥為【锛?/p>

鎵嬫妸鎵嬫惌寤篧ebSocket澶氫汉鍦ㄧ嚎鑱婂ぉ瀹わ紙SpringBoot+WebSocket锛?/p>

[WebSocket]绗簩绔狅細WebSocket闆嗙兢鍒嗗竷寮忔敼閫犫€斺€斿疄鐜板浜哄湪绾胯亰澶╁

鍦ㄦ湰鏂囦腑锛屾垜灏嗕粙缁嶅浣曚娇鐢╓ebSocket鍚戝疄鏃跺浜虹瓟棰樺鎴樻父鎴忔彁渚涙湇鍔$锛屽苟璇︾粏浠嬬粛閫氭帴鍙g殑璁捐銆?/p>

杩欐槸鎴戝湪鏈€杩戜綔涓氱珵璧涗腑璁捐鐨勫皬椤圭洰锛屽拰灏忎紮浼翠滑涓€璧疯璁′簡鏁翠釜娓告垙娴佺▼鍜屽悗绔唬鐮侊紝鍓嶇椤甸潰鏆傛椂灏变笉鏀惧紑缁欏ぇ瀹朵簡锛屽ぇ瀹跺彲浠ュ弬鑰冨墠涓ょ珷鏁欑▼鑷繁鍔ㄦ墜鍐欎竴涓嬪墠绔〉闈€?/p>

鏈枃鍐呭鎽樿锛?/p>

  • 鍦ㄧ嚎娓告垙甯哥敤鐨勯€氳鏂规
  • 濡備綍浣跨敤WebSocket瀹炵幇娓告垙瀵规垬瀹炴椂閫氫俊
  • 娓告垙姝ラ鐨勭敾闈㈡紨绀哄拰瀵瑰簲鐨刉ebSocket鎺ュ彛璁捐

鏈枃婧愮爜锛氾紙濡堝鍐嶄篃涓嶇敤鎷呭績鎴戞棤娉曞鐜版枃绔犱唬鐮佸暒锛?/p>

https://github.com/qqxx6661/websocket-game-demo

姝f枃

WebSocket瀹炵幇鍦ㄧ嚎澶氫汉娓告垙鈥斺€斿鎴樼瓟棰?/h2>

鍦ㄧ嚎娓告垙甯哥敤鐨勯€氳鏂规

鍙傝€冿細

https://blog.csdn.net/honey199396/article/details/54603860

HTTP

浼樼偣锛氬崗璁緝鎴愮啛锛屽簲鐢ㄥ箍娉涖€佸熀浜嶵CP/IP锛屾嫢鏈塗CP浼樼偣銆佺爺鍙戞垚鏈緢浣庯紝寮€鍙戝揩閫熴€佸紑婧愯蒋浠惰緝澶氾紝nginx,apache,tomact绛?br/>缂虹偣锛氭棤鐘舵€佹棤杩炴帴銆佸彧鏈塒ULL妯″紡锛屼笉鏀寔PUSH銆佹暟鎹姤鏂囪緝澶?br/>鐗规€э細鍩轰簬TCP/IP搴旂敤灞傚崗璁€佹棤鐘舵€侊紝鏃犺繛鎺ャ€佹敮鎸丆/S妯″紡銆侀€傜敤浜庢枃鏈紶杈?/p>

TCP

浼樼偣锛氬彲闈犳€?銆佸叏鍙屽伐鍗忚銆佸紑婧愭敮鎸佸銆佸簲鐢ㄨ緝骞挎硾銆侀潰鍚戣繛鎺ャ€佺爺鍙戞垚鏈綆銆佹姤鏂囧唴瀹逛笉闄愬埗锛圛P灞傝嚜鍔ㄥ垎鍖咃紝閲嶄紶锛屼笉澶т簬1452bytes锛?br/>缂虹偣锛氭搷浣滅郴缁燂細杈冭€楀唴瀛橈紝鏀寔杩炴帴鏁版湁闄愩€佽璁★細鍗忚杈冨鏉傦紝鑷畾涔夊簲鐢ㄥ眰鍗忚銆佺綉缁滐細缃戠粶宸儏鍐典笅寤惰繜杈冮珮銆佷紶杈擄細鏁堢巼浣庝簬UDP鍗忚
鐗规€э細闈㈠悜杩炴帴銆佸彲闈犳€с€佸叏鍙屽伐鍗忚銆佸熀浜嶪P灞傘€丱SI鍙傝€冩ā鍨嬩綅浜庝紶杈撳眰銆侀€傜敤浜庝簩杩涘埗浼犺緭

WebScoket

浼樼偣锛氬崗璁緝鎴愮啛銆佸熀浜嶵CP/IP锛屾嫢鏈塗CP浼樼偣銆佹暟鎹姤鏂囪緝灏忥紝鍖呭ご闈炲父灏忋€侀潰鍚戣繛鎺ワ紝鏈夌姸鎬佸崗璁€佸紑婧愯緝澶氾紝寮€鍙戣緝蹇?br/>缂虹偣锛?br/>鐗规€э細鏈夌姸鎬侊紝闈㈠悜杩炴帴銆佹暟鎹姤澶磋緝灏忋€侀€傜敤浜嶹EB3.0锛屼互鍙婂叾浠栧嵆鏃惰仈缃戦€氳

UDP

浼樼偣锛氭搷浣滅郴缁燂細骞跺彂楂橈紝鍐呭瓨娑堣€楄緝浣庛€佷紶杈擄細鏁堢巼楂橈紝缃戠粶寤惰繜浣庛€佷紶杈撴ā鍨嬬畝鍗曪紝鐮斿彂鎴愭湰浣?br/>缂虹偣锛氬崗璁笉鍙潬銆佸崟鍚戝崗璁€佸紑婧愭敮鎸佸皯銆佹姤鏂囧唴瀹规湁闄愶紝涓嶈兘澶т簬1464bytes銆佽璁★細鍗忚璁捐杈冨鏉傘€佺綉缁滐細缃戠粶宸紝鑰屼笖涓㈡暟鎹姤鏂?br/>鐗规€э細鏃犺繛鎺ワ紝涓嶅彲闈狅紝鍩轰簬IP鍗忚灞傦紝OSI鍙傝€冩ā鍨嬩綅浜庝紶杈撳眰锛屾渶澶у姫鍔涗氦浠橈紝閫傜敤浜庝簩杩涘埗浼犺緭

鎬荤粨

  • 瀵逛簬寮辫仈缃戠被娓告垙锛屽繀椤绘秷闄ょ被鐨勶紝鍗$墝绫荤殑锛屽彲浠ョ洿鎺TTP鍗忚锛岃€冭檻瀹夊叏鐨勮瘽鐩存帴HTTPS锛屾垨鑰呭鍐呭浣撳仛瀵圭О鍔犲瘑锛?/li>
  • 瀵逛簬瀹炴椂鎬э紝浜や簰鎬ц姹傝緝楂橈紝鍙互浼樺厛閫夋嫨Websocket锛屽叾娆CP鍗忚锛?/li>
  • 瀵逛簬瀹炴椂鎬ц姹傛瀬楂橈紝涓斿彲杈炬€ц姹備竴鑸彲浠ラ€夋嫨UDP鍗忚锛?/li>
  • 灞€鍩熺綉瀵规垬绫伙紝璧涜溅绫伙紝鐩存帴鏉DP鍗忚鍚э紱

WebSocket瀹炵幇鍙屼汉鍦ㄧ嚎娓告垙瀹炴椂閫氫俊

鎴戜滑閲囩敤websocket浣滀负鎴戜滑鐨勯€氫俊鏂规锛屼富瑕佹槸鍥犱负鎴戜滑甯屾湜瀵规垬鍙屾柟鑳藉瀹炴椂鏄剧ず瀵规柟鐨勫緱鍒嗐€?/p>

鏈皬鑺傝缁嗕粙缁嶄簡鎴戜滑鍦ㄧ嚎闂瓟瀵规垬娓告垙涓紝鍏蜂綋鐨剋ebsocket閫氳鏂瑰紡瀹氫箟銆?/p>

鏈棶绛旀父鎴忚鍒欏涓嬶細

  • 鐢ㄦ埛鎵撳紑h5椤甸潰鍚庯紝杈撳叆鑷繁鐨勬樀绉帮紝鍙戦€佺粰鏈嶅姟绔紝鏈嶅姟绔皢鐢ㄦ埛鏄电О淇濆瓨鍒癶ashmap锛屽苟璁板綍鐢ㄦ埛鐘舵€侊紙绌洪棽锛屾父鎴忎腑锛夛紝鎺ョ潃鐢ㄦ埛杩涘叆澶у巺銆?/li>
  • 澶у巺涓敤鎴峰彲浠ヤ簰鐩搁€夋嫨锛屼竴鏃︽煇鐢ㄦ埛閫夋嫨浜嗗彟涓€浣嶇敤鎴凤紝灏嗚Е鍙戝紑濮嬫父鎴忥紝鍙屾柟杩涘叆绛旈妯″紡銆?/li>
  • 绛旈鐨勪袱浣嶇敤鎴峰悇鍥炵瓟10棰橈紝姣忛绛斿涓?0鍒嗭紝鍏?00鍒嗭紝宸︿笂瑙掗〉闈㈡樉绀鸿嚜宸辩殑鍒嗘暟锛屽彸涓婅鏄剧ず瀵规柟鍒嗘暟锛屽疄鏃堕€氳繃websocket鎺ユ敹瀵规柟鍒嗘暟銆?/li>
  • 10棰樼粨鏉燂紝鍙屾柟绛夊緟瀵规柟鎬诲垎锛屾渶鍚庡垽鏂緭璧紝鏄剧ず缁撴灉鐣岄潰銆?/li>

鎵€浠ユ垜浠渶瑕佽璁′笁涓猈ebSocket鍗忚锛?/h3>
  • 鐢ㄦ埛鍒涘缓鏄电О锛岃繘鍏ョ帺瀹跺ぇ鍘?/li>
  • 鐢ㄦ埛閫夋嫨瀵规墜锛屽弻鏂硅繘鍏ユ父鎴?/li>
  • 瀵规垬杩囩▼瀹炴椂鏄剧ず鍙屾柟鍒嗘暟

鎺ヤ笅鏉ヨ缁嗕粙缁嶈繖涓夌WebSocket鎺ュ彛

鐢ㄦ埛鍒涘缓鏄电О锛岃繘鍏ョ帺瀹跺ぇ鍘?/h3>

鎵撳紑鐣岄潰锛岃繘鍏ユ父鎴忥細
鎶€鏈浘鐗? src=

鎴戜滑浣跨敤浜咹ashMap瀛樺偍鐢ㄦ埛鐘舵€侊紝

private Map<String, StatusEnum> userToStatus = new HashMap<>();

鐢ㄦ埛鐘舵€佸垎涓虹┖闂插拰娓告垙涓細

public enum StatusEnum {
    IDLE,
    IN_GAME
}

WebSocket鎺ュ彛璁捐濡備笅锛?br/>鎶€鏈浘鐗? src=

WebSocket鎺ュ彛浠g爜濡備笅锛?/p>

@MessageMapping("/game.add_user")
    @SendTo("/topic/game")
    public MessageReply addUser(@Payload ChatMessage chatMessage, SimpMessageHeaderAccessor headerAccessor) throws JsonProcessingException {
        MessageReply message = new MessageReply();
        String sender = chatMessage.getSender();
        ChatMessage result = new ChatMessage();
        result.setType(MessageTypeEnum.ADD_USER);
        result.setReceiver(Collections.singletonList(sender));
        if (userToStatus.containsKey(sender)) {
            message.setCode(201);
            message.setStatus("璇ョ敤鎴峰悕宸插瓨鍦?);
            message.setChatMessage(result);
            log.warn("addUser[" + sender + "]: " + message.toString());
        } else {
            result.setContent(mapper.writeValueAsString(userToStatus.keySet().stream().filter(k -> userToStatus.get(k).equals(StatusEnum.IDLE)).toArray()));
            message.setCode(200);
            message.setStatus("鎴愬姛");
            message.setChatMessage(result);
            userToStatus.put(sender, StatusEnum.IDLE);
            headerAccessor.getSessionAttributes().put("username",sender);
            log.warn("addUser[" + sender + "]: " + message.toString());
        }
        return message;
    }

鐢ㄦ埛閫夋嫨瀵规墜锛屽弻鏂硅繘鍏ユ父鎴?/h3>

鍦ㄥぇ鍘呬腑閫夋嫨鐜╁锛岄殢鍚庝細杩涘叆瀵规垬锛?/p>

鎶€鏈浘鐗? src=

鎴戜滑浣跨敤浜咹ashMap瀛樺偍浜嗘鍦ㄥ鎴樼殑鐢ㄦ埛锛岀粰鍙屾柟閰嶅銆?/p>

private Map<String, String> userToPlay = new HashMap<>();

WebSocket鎺ュ彛璁捐濡備笅锛?br/>鎶€鏈浘鐗? src=

WebSocket鎺ュ彛浠g爜濡備笅锛?/p>

@MessageMapping("/game.choose_user")
    @SendTo("/topic/game")
    public MessageReply chooseUser(@Payload ChatMessage chatMessage) throws JsonProcessingException {
        MessageReply message = new MessageReply();
        String receiver = chatMessage.getContent();
        String sender = chatMessage.getSender();
        ChatMessage result = new ChatMessage();
        result.setType(MessageTypeEnum.CHOOSE_USER);
        if (userToStatus.containsKey(receiver) && userToStatus.get(receiver).equals(StatusEnum.IDLE)) {
            List<QuestionRelayDTO> list=new ArrayList<>();
            questionService.getQuestions(limit).forEach(item->{
                QuestionRelayDTO relayDTO=new QuestionRelayDTO();
                relayDTO.setTopic_id(item.getId());
                relayDTO.setTopic_name(item.getQuestion());
                List<Answer> answers=new ArrayList<>();
                answers.add(new Answer(1,item.getId(),item.getOptionA(),item.getResult()==1?1:0));
                answers.add(new Answer(2,item.getId(),item.getOptionB(),item.getResult()==2?1:0));
                answers.add(new Answer(3,item.getId(),item.getOptionC(),item.getResult()==3?1:0));
                answers.add(new Answer(4,item.getId(),item.getOptionD(),item.getResult()==4?1:0));
                relayDTO.setTopic_answer(answers);
                list.add(relayDTO);
            });
            result.setContent(mapper.writeValueAsString(list));
            result.setReceiver(Arrays.asList(sender, receiver));
            message.setCode(200);
            message.setStatus("鍖归厤鎴愬姛");
            message.setChatMessage(result);
            userToStatus.put(receiver, StatusEnum.IN_GAME);
            userToStatus.put(sender, StatusEnum.IN_GAME);
            userToPlay.put(receiver,sender);
            userToPlay.put(sender,receiver);
            log.warn("chooseUser[" + sender + "," + receiver + "]: " + message.toString());
        } else {
            result.setContent(mapper.writeValueAsString(userToStatus.keySet().stream().filter(k -> userToStatus.get(k).equals(StatusEnum.IDLE)).toArray()));
            result.setReceiver(Collections.singletonList(sender));
            message.setCode(202);
            message.setStatus("璇ョ敤鎴蜂笉瀛樺湪鎴栧凡鍦ㄦ父鎴忎腑");
            message.setChatMessage(result);
            log.warn("chooseUser[" + sender + "]: " + message.toString());
        }
        return message;
    }

瀵规垬杩囩▼瀹炴椂鏄剧ず鍙屾柟鍒嗘暟

瀵规垬杩囩▼涓殑婕旂ず鍥撅細宸﹁竟鏄剧ず鎴戞柟鍒嗘暟锛屽彸杈规樉绀哄鏂瑰垎鏁?br/>鎶€鏈浘鐗? src=

WebSocket鎺ュ彛璁捐濡備笅锛?br/>鎶€鏈浘鐗? src=

WebSocket鎺ュ彛浠g爜濡備笅锛?/p>

@MessageMapping("/game.do_exam")
    @SendTo("/topic/game")
    public MessageReply doExam(@Payload ChatMessage chatMessage) throws JsonProcessingException {
        MessageReply message = new MessageReply();
        String sender = chatMessage.getSender();
        String receiver = userToPlay.get(sender);
        ChatMessage result = new ChatMessage();
        result.setType(MessageTypeEnum.DO_EXAM);
        log.warn("userToStatus:" + mapper.writeValueAsString(userToStatus));
        if (userToStatus.containsKey(receiver) && userToStatus.get(receiver).equals(StatusEnum.IN_GAME)) {
            result.setContent(chatMessage.getContent());
            result.setSender(sender);
            result.setReceiver(Collections.singletonList(receiver));
            message.setCode(200);
            message.setStatus("鎴愬姛");
            message.setChatMessage(result);
            log.warn("doExam[" + receiver + "]: " + message.toString());
        }else{
            result.setReceiver(Collections.singletonList(sender));
            message.setCode(203);
            message.setStatus("璇ョ敤鎴蜂笉瀛樺湪鎴栧凡閫€鍑烘父鎴?);
            message.setChatMessage(result);
            log.warn("doExam[" + sender + "]: " + message.toString());
        }
        return message;
    }

杩涗竴姝?/h3>

杩欎釜鍙槸涓袱澶╄刀鍑烘潵鐨凞emo锛屽綋鐒堕噷鎴愬搧杩樻湁闈炲父澶х殑宸窛銆傝繖閲屾湁鍑犱釜闇€瑕佺户缁В鍐崇殑浜嬫儏锛?/p>

  • 瀹炵幇鑷姩鍖归厤/鎺掕姒?/li>
  • WebSocket閫氳浼樺寲锛氬湪鏌愪簺鍦版柟浣跨敤鐐瑰鐐归€氳锛岃€岄潪鍏ㄩ儴浣跨敤骞挎挱閫氳銆?/li>

鎴戜滑鍙互浣跨敤convertAndSendToUser()鏂规硶锛屾寜鐓у悕瀛楀氨鍙互鍒ゆ柇鍑烘潵锛宑onvertAndSendToUser()鏂规硶鑳藉璁╂垜浠粰鐗瑰畾鐢ㄦ埛鍙戦€佹秷鎭€?br/>spring webscoket鑳借瘑鍒甫鈥?user鈥濈殑璁㈤槄璺緞骞跺仛鍑哄鐞嗭紝渚嬪锛屽鏋滄祻瑙堝櫒瀹㈡埛绔紝璁㈤槄浜嗏€?user/topic/greetings鈥欒繖鏉¤矾寰勶紝

stompClient.subscribe(鈥?user/topic/greetings鈥? function(data) {
    //...
});

灏变細琚玸pring websocket鍒╃敤UserDestinationMessageHandler杩涜杞寲鎴愨€?topic/greetings-usererbgz2rq鈥?鈥漸sererbgz2rq鈥濅腑锛寀ser鏄叧閿瓧锛宔rbgz2rq鏄痵essionid锛岃繖鏍峰瓙灏辨妸鐢ㄦ埛鍜岃闃呰矾寰勫敮涓€鐨勫尮閰嶈捣鏉ヤ簡.

鍙傝€冩枃鐚?/h1>

鐐瑰鐐归€氳锛?/p>

https://blog.csdn.net/yingxiake/article/details/51224569

鎬荤粨

鎴戜滑鍦ㄦ湰鏂囦腑瀹炵幇浜嗗湪绾垮浜哄鎴樻父鎴忕殑鏈嶅姟绔疻ebSocket鎺ュ彛璁捐锛岃繘涓€姝ュ珐鍥轰簡瀵筗ebSocket鐨勫熀纭€鍜屽簲鐢ㄨ寖鍥寸殑鐞嗚В銆?/p>

鏈枃宸ョ▼婧愪唬鐮侊細

https://github.com/qqxx6661/websocket-game-demo

鍏虫敞鎴?/h1>

鎴戠洰鍓嶆槸涓€鍚嶅悗绔紑鍙戝伐绋嬪笀銆備富瑕佸叧娉ㄥ悗绔紑鍙戯紝鏁版嵁瀹夊叏锛岀埇铏紝杈圭紭璁$畻绛夋柟鍚戙€?/p>

寰俊锛歽angzd1102锛堣娉ㄦ槑鏉ユ剰锛?/p>

Github锛欯qqxx6661

涓汉鍗氬锛?/p>

  • CSDN锛欯Rude3Knife
  • 鐭ヤ箮锛欯Zhendong
  • 绠€涔︼細@铔笁鍒€鎶婂垁
  • 鎺橀噾锛欯铔笁鍒€鎶婂垁

鍘熷垱鍗氬涓昏鍐呭

  • Java鐭ヨ瘑鐐瑰涔犲叏鎵嬪唽
  • Leetcode绠楁硶棰樿В鏋?/li>
  • 鍓戞寚offer绠楁硶棰樿В鏋?/li>
  • SpringCloud鑿滈笩鍏ラ棬瀹炴垬绯诲垪
  • SpringBoot鑿滈笩鍏ラ棬瀹炴垬绯诲垪
  • 鐖櫕鐩稿叧鎶€鏈枃绔?/li>
  • 鍚庣寮€鍙戠浉鍏虫妧鏈枃绔?/li>

涓汉鍏紬鍙凤細鍚庣鎶€鏈极璋?/h3>

鎶€鏈浘鐗? src=
涓汉鍏紬鍙凤細鍚庣鎶€鏈极璋?/p>

濡傛灉鏂囩珷瀵逛綘鏈夊府鍔╋紝涓嶅Θ鏀惰棌璧锋潵骞惰浆鍙戠粰鎮ㄧ殑鏈嬪弸浠瑍

以上是关于[WebSocket]浣跨敤WebSocket瀹炵幇瀹炴椂澶氫汉绛旈瀵规垬娓告垙的主要内容,如果未能解决你的问题,请参考以下文章

Java浣跨敤swing缁勪欢瀹炵幇绠€鏄撹绠楀櫒

js瀹炵幇60s鍊掕鏃舵晥鏋滅敤浜庤幏鍙栫煭淇¢獙璇佺爜浣跨敤

Python鐨凘property浣跨敤鏂规硶璇﹁В

Asp.Net浣跨敤Yahoo.Yui.Compressor.dll鍘嬬缉Js|Css

濡備綍浣跨敤eclipse浣跨敤Maven