From 01 onwards Learn Spring boot Layim project into Mind (v) websocket

Source: Internet
Author: User

Objective

It's been a long time since the last one, and the project has started. And, because of the online on the spring boot websocket explanation is also more. So I used another communication framework T-io to implement the communication function in Layim. This article will focus on the parts of the pits and the time spent comparing my research and development process.

WebSocket

In the study of T-io , I have written about the T-io framework of a few simple examples of analysis and the framework of the websocket in the coding and decoding code analysis, interested students can first look. Because in the Layim project I will use the Showcase Demo design ideas.

Communication Framework T-io Learning--an analysis of demo:showcase design for Beginners

Communication Framework T-io Learning--websocket Part source parsing

If you want to learn these things, I still suggest to calm down to see. Why not use the spring Boot packaged websocket? Because it is packaged too well, many businesses cannot be customized. And through the T-io framework to develop their own websocket end, it is more flexible. Can even create a specially tailored for Layim WebSocket service, before explaining my development road, but also to recommend a more complete solution Tio-im, of course, I also learn from the source code design ideas. But its implementation is more powerful, because my level is limited, I can only Tiger, carelessly wrote a pass. But it can still be used.

Tio-im Address: Https://gitee.com/xchao/tio-im

Project Combat

The first few have implemented the Layim main interface data loading function. Next is the core part of the communication. There are many ways to achieve this, and here I use the websocket based on the T-io communication framework. Before entering the detailed code, we will first analyze some of the function points used in Layim.

    • Login function
    • Single chat feature
    • Group Chat Feature
    • Additional custom message alert features
    • Wait a minute....

  The purpose of the login is to filter the illegal request, if an illegal user requests the WebSocket service, return 403 or 401 directly.

Single chat, group chat This is not explained.

Other custom message reminders, such as: Always add friend messages, broadcast messages, audit messages and so on.

  The outgoing message interface in T-io is implemented in Aio.java . (only part of the interface is listed below and used in the Layim project)

//bind user Public Static voidBinduser (Channelcontext channelcontext, String userid)//Send to User Public StaticBoolean Sendtouser (groupcontext groupcontext, String userid, Packet Packet)//Send to Group Public Static voidSendtogroup (Groupcontext groupcontext, String Group, Packet Packet)//Send to everyone Public Static voidSendtoall (Groupcontext groupcontext, Packet Packet)//Send to specified channel Public StaticBoolean Send (Channelcontext channelcontext, Packet Packet)

Before we start, we're going to develop the message codec class (already implemented in the framework), the handling of the message listener event, because for Layim we have business-based custom development, so we will change some of the source code. What about me? Paste some of the source code in the framework into the project, and then make the changes. But like for example: handshake process, upgrade WebSocket connection, parse byte[] These functions we do not need to do, want to learn, you can look at the source code to study. OK, let's go into the code section.

Code anatomy

First implement the Iwsmsghandler interface. This interface is defined in org. tio. websocket. server. in the handler package, the code is as follows.

 Public InterfaceIwsmsghandler {/** * The HttpResponse parameter is supplemented and returned, if the return null means that you do not want to establish a connection with the other, the framework will be disconnected, if the return is non-null, the framework will send this object to the other side*/     PublicHttpResponse Handshake (HttpRequest HttpRequest, HttpResponse HttpResponse, Channelcontext ChannelContext) throws    Exception; /** * @return can be wsresponse, byte[], Bytebuffer, string, or NULL, if NULL, the framework does not return messages*/Object onbytes (wsrequest wsrequest,byte[] bytes, Channelcontext channelcontext) throws Exception; /** * @return can be wsresponse, byte[], Bytebuffer, string, or NULL, if NULL, the framework does not return messages*/Object onClose (wsrequest wsrequest,byte[] bytes, Channelcontext channelcontext) throws Exception; /** * @return can be wsresponse, byte[], Bytebuffer, string, or NULL, if NULL, the framework does not return messages*/Object Ontext (wsrequest wsrequest, String text, Channelcontext channelcontext) throws Exception;}

In general, we will do something in the public interface implementations, such as

   @Override    public  Object ontext (wsrequest wsrequest, String s, channelcontext Channelcontext) throws Exception {        logger.info (" receive text message ");         // message Business processing logic        return " message sent successfully " ;    }    

But since this time we can write our own websocket internal business logic, we are not dealing with the main business logic in these interfaces. So where does the main business logic work? I put him behind the decode method. Maybe, people see here a bit dizzy, below I draw a picture to introduce a message from the overall situation of the delivery process. Here I send a message with a single chat example.

  

First, the client connects to the server. Take the handshake process first.

if(!wssessioncontext.ishandshaked ()) {HttpRequest request=httprequestdecoder.decode (buffer, channelcontext); if(Request = =NULL) {                return NULL; }//Upgrade to WEBSOKCET protocol HttpResponse HttpResponse=Protocol.updatetowebsocket (Request, Channelcontext); if(HttpResponse = =NULL) {                Throw NewAiodecodeexception ("HTTP protocol upgrade to WebSocket protocol failed");            } wssessioncontext.sethandshakerequestpacket (Request);            Wssessioncontext.sethandshakeresponsepacket (HttpResponse); Wsrequest Wsrequestpacket=Newwsrequest (); Wsrequestpacket.sethandshake (true); returnWsrequestpacket; }
 wssessioncontext wssessioncontext = (Wssessioncontext) Channelcontext.getattribu            Te ();            HttpRequest request  = Wssessioncontext.gethandshakerequestpacket ();       HttpResponse httpresponse  = Wssessioncontext.gethandshakeresponsepacket (); 
Here, the return value is implemented by the handshake interface to determine if the handshake is agreed HttpResponse R = Wsmsghandler.handshake (re Quest, HttpResponse, Channelcontext); if (r = = null ) {Aio.remove (Channelcontext, " The business layer disagrees with the handshake " ); return ; }

The Wsmsghandler.handshake method in the second paragraph of the preceding code, which is typically returned directly to the default Httpreponse, represents the (frame-level) handshake success. But we can customize some of the business logic in the interface, such as the logic of user judgment, and then decide whether to agree to the handshake process.

Here's a little detail to note, whether it's a handshake or a business login request, after success, you need to bind the user to the current context (Channelcontext). Call Aio.binduser .

Send Message flow for a simple version of chat: Client A sends a message to client B.

  

As mentioned above, the codec we do not care too much, then we need to focus on the business process. The design idea is also very easy to think about, first of all, we have different message types. This message type is determined by the client. If the wrong message type is passed in, an exception is thrown or an unknown message processing is returned. The message processing class structure is designed as follows:

  

is not very simple, a generic business processing portal, the message into a friendly class entity, and then in the specific Message Processor processing business logic.

The Layimabsmsgprocessor core code is as follows:

   /** * This uses the design idea in the showcase (after deserializing the message, processed by the specific message processor) **/@Override Publicwsresponse Process (wsrequest layimpacket, Channelcontext channelcontext) throws Exception {Class<T> Clazz =Getbodyclass (); T Body=NULL; if(Layimpacket.getbody ()! =NULL) {//get data in JSON formatString JSON =Byteutil.totext (Layimpacket.getbody ()); //to convert a string to a specific type of objectBODY =Json.tobean (Json, clazz); }//processing a Message object through a specific processing class        returnprocess (Layimpacket, body, channelcontext); }     Public  AbstractWsresponse process (wsrequest layimpacket,t body,channelcontext channelcontext) throws Exception;

The Clienttoclientmsgprocessor core code is as follows:

@Override Publicwsresponse Process (wsrequest layimpacket, chatrequestbody body, Channelcontext channelcontext) throws Exception { //requestbody the type of message converted to the receiving endClienttoclientmsgbody Msgbody =bodyconvert.getinstance (). Converttomsgbody (Body,channelcontext); //message Wrapping, returning WsresponseWsresponse response =bodyconvert.getinstance (). Converttotextresponse (Msgbody); //get each other's ChannelcontextChannelcontext Tochannelcontext =Aio.getchannelcontextbyuserid (Channelcontext.getgroupcontext (), body.gettoid ()); //Send to each otheraio.send (Tochannelcontext,response); return NULL; }
Docking Spring Boot

So how to start the WebSocket service, the general framework is bound well. Here we have a special deal, just at first I was manually calling the Start method, and later studied Spring boot starter. The following is a brief introduction to the use of starter.

First, create a configuration class.

@ConfigurationProperties ("Layim.websocket") Public classlayimserverproperties { Publiclayimserverproperties () {Port=8081; Heartbeattimeout=0; IP=NULL; }        //Getter Setter    Private intPort; Private intheartbeattimeout; PrivateString IP;}

Part II, create a new AutoConfig class

@Configuration @enableconfigurationproperties (layimserverproperties.class) Public classlayimwebsocketserverautoconfig {@Autowired layimserverproperties properties; @Bean Layimwebsocketstarter Layimwebsocketstarter () throws exception{//Initializing configuration informationLayimserverconfig config =NewLayimserverconfig (Properties.getport ());        Config.setbindip (Properties.getip ());        Config.setheartbeattimeout (Properties.getheartbeattimeout ()); Layimwebsocketstarter Layimwebsocketstarter=Newlayimwebsocketstarter (config); //Start the serviceLayimwebsocketstarter.start (); //return        returnLayimwebsocketstarter; }}

The third step, under the Resources folder, create a new Meta-inf folder, in the new Spring.factories file, the contents of the file:

org.springframework.boot.autoconfigure.enableautoconfiguration= Com.fyp.layim.im.server.LayimWebsocketServerAutoConfig

OK, let's configure it here.

  

Then start the program.

  

Start successfully!

Project Demo

It's a lot to talk about, but to show you the demo.

User 1, 2 linked server.

  

User 2 sends a message to User 1:

  

Look at the above is just the demo message can be sent smoothly, the following log print diagram can be seen to the server processing process.

  

Summarize

So far we've been able to communicate, but that's not enough and there's more business to deal with. But it doesn't matter, the communication is realized, the rear is not difficult. In fact, more is the details of the grasp, such as user retirement group, users offline, statistics users online number.

Next announcement: Starting from 01 Layim project to learn spring boot (v) Implementation of user login verification and single chat group chat

Github:https://github.com/fanpan26/springbootlayim

From 01 onwards Learn Spring boot Layim project into Mind (v) websocket

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.