preface

In the first two tutorials, we built a small chat room using the basic features of WebSocket, and in the second we clustered it.

Series review:

[WebSocket] Chapter 1: Hand-to-hand WebSocket multiplayer online chat room (SpringBoot+WebSocket)

Chapter 2: WebSocket cluster distributed transformation — realize multi-person online chat room

In this article, I’ll show you how to use WebSocket to provide a server for real-time multiplayer answer sheet games and detail the design of the general interface.

This is a small project I designed in the recent homework competition. I designed the whole game process and back-end code with my friends. The front-end page is not open to you for the time being.

Abstract:

  • Communication schemes commonly used in online games
  • How to use WebSocket to achieve real-time game communication
  • Screen demonstration of game steps and corresponding WebSocket interface design

Mom doesn’t have to worry that I won’t be able to reproduce the article code anymore.

Github.com/qqxx6661/we…

The body of the

WebSocket to achieve online multiplayer games – battle answer

Communication schemes commonly used in online games

Reference:

Blog.csdn.net/honey199396…

HTTP

Advantages: mature protocol, widely used, based on TCP/IP, with TCP advantages, low r&d cost, rapid development, more open source software, such as Nginx, Apache, Tomact, etc

Disadvantages: Stateless, no connection, only PULL mode, does not support PUSH, large data packets

Features: Based on TCP/IP application layer protocol, stateless, connectionless, supports C/S mode, suitable for text transmission

TCP

Advantages: Reliability, full-duplex protocol, open source support, wide application, connection-oriented, low r&d cost, unlimited packet content (automatic subcontracting and retransmission at the IP layer, not larger than 1452bytes)

Disadvantages: Operating system: high memory consumption, limited number of connections supported, design: complex protocols, customized application-layer protocols, network: high latency in poor network conditions, lower transmission efficiency than UDP

Features: connection-oriented, reliable, full-duplex protocol, IP layer based, OSI reference model in transport layer, suitable for binary transport

WebScoket

Advantages: Mature protocol, BASED on TCP/IP, with TCP advantages, small data packets, very small packet header, connection-oriented, stateful protocol, more open source, rapid development

Disadvantages:

Features: stateful, connection-oriented, small data header, suitable for WEB3.0, and other instant networking

UDP

Advantages: Operating system: high concurrency, low memory consumption, transmission: high efficiency, low network delay, simple transmission model, low r&d cost

Disadvantages: unreliable protocol, unidirectional protocol, little open source support, limited packet content (no more than 1464bytes), design: complex protocol design, network: poor network, and loss of data packets

Features: connectionless, unreliable, based on IP protocol layer, OSI reference model located in transport layer, best effort delivery, suitable for binary transport

conclusion

  • For weak networking games, must eliminate class, card class, can directly HTTP protocol, consider the security of direct HTTPS, or to do symmetric encryption of the content body;
  • For real-time, interactive requirements are high, can choose Websocket first, TCP protocol second;
  • For high real-time requirements, and reachable requirements can generally choose UDP protocol;
  • LAN versus class, racing class, directly to UDP protocol;

WebSocket realtime communication for two – person online game

We used Websocket as our communication solution mainly because we wanted both sides to be able to display each other’s scores in real time.

This section details the definition of websocket communication in our online quiz game.

The rules of this game are as follows:

  • After opening the H5 page, the user enters his nickname and sends it to the server. The server saves the nickname into the HashMap and records the user status (idle, in game). Then the user enters the lobby.
  • Users can choose each other in the hall. Once a user chooses another user, the game will be triggered and both sides will enter the answer mode.
  • The two users answered 10 questions each, 10 points for each correct answer, a total of 100 points, the upper left corner of the page to display their score, the upper right corner of the other side’s score, real-time receive the other side’s score through websocket.
  • At the end of question 10, the two sides wait for the total score of the other side and judge the winner and display the result interface.

So we need to design three WebSocket protocols:

  • Users create nicknames and enter the player lobby
  • The user selects the opponent and both sides enter the game
  • Real-time display of the scores of both sides during the battle

The three WebSocket interfaces are described in detail next

Users create nicknames and enter the player lobby

Open the interface and enter the game:

We used HashMap to store user status,

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

User states are divided into idle and game:

public enum StatusEnum {
    IDLE,
    IN_GAME
}
Copy the code

The WebSocket interface design is as follows:

The WebSocket interface code is as follows:

@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("The username already exists");
            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("Success");
            message.setChatMessage(result);
            userToStatus.put(sender, StatusEnum.IDLE);
            headerAccessor.getSessionAttributes().put("username",sender);
            log.warn("addUser[" + sender + "]." + message.toString());
        }
        return message;
    }
Copy the code

The user selects the opponent and both sides enter the game

Select the player in the hall, and then enter the battle:

We used a HashMap to store users who were playing against each other and match them.

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

The WebSocket interface design is as follows:

The WebSocket interface code is as follows:

@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("Match successful");
            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("The user does not exist or is already in the game");
            message.setChatMessage(result);
            log.warn("chooseUser[" + sender + "]." + message.toString());
        }
        return message;
    }
Copy the code

Real-time display of the scores of both sides during the battle

Demo diagram in the process of battle: the left side shows our score, the right side shows the other side’s score

The WebSocket interface design is as follows:

The WebSocket interface code is as follows:

@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("Success");
            message.setChatMessage(result);
            log.warn("doExam[" + receiver + "]." + message.toString());
        }else{
            result.setReceiver(Collections.singletonList(sender));
            message.setCode(203);
            message.setStatus("The user does not exist or has quit the game.");
            message.setChatMessage(result);
            log.warn("doExam[" + sender + "]." + message.toString());
        }
        return message;
    }
Copy the code

further

This is only a two-day Demo, of course, there is still a big gap in the finished product. Here are a few things to work on:

  • Implement automatic matching/leaderboards
  • WebSocket communication optimization: Use point-to-point communication in some places rather than all broadcast communication.

We can use the convertAndSendToUser() method, which by its name allows us to send a message to a particular user.

Spring Webscoket recognizes a subscription path with “/user” and handles it. For example, if a browser client subscribs to a path with “/user/topic/greetings”,

stompClient.subscribe('/user/topic/greetings'.function(data) {
    //...
});
Copy the code

Will be spring websocket using UserDestinationMessageHandler into “/ topic/’t – usererbgz2rq”,” In usererbgz2rq, user is the keyword and erbgz2rq is the sessionID, which uniquely matches the user to the subscription path

reference

Point-to-point communication:

Blog.csdn.net/yingxiake/a…

conclusion

In this paper, we implement the server WebSocket interface design of online multiplayer game, and further consolidate the understanding of the foundation and application scope of WebSocket.

This article project source code:

Github.com/qqxx6661/we…

Pay attention to my

I am currently working as a back-end development engineer. Focus on back-end development, data security, crawler, edge computing, etc.

Wechat: Yangzd1102 (please specify the purpose of your visit)

Making: @ qqxx6661

Personal Blog:

  • CSDN: @ Rude3Knife
  • Zhihu: @ Zhendong
  • Jane: @pretty three knives a knife
  • Nuggets: @ pretty three knife knife

Original blog main content

  • Java knowledge points review the full manual
  • Leetcode algorithm parsing
  • Sword point offer algorithm analysis
  • SpringCloud rookie combat series
  • SpringBoot rookie combat series
  • Crawler related technical articles
  • Technical articles related to back-end development

Personal public account: Back-end technology ramble

If this article is helpful to you, save it and send it to your friends