WebSocket+Springboot

1.1 PoM file dependencies and plug-ins

<parent>





<groupId>

org.springframework.boot

</groupId>





<artifactId>

spring-boot-starter-parent

</artifactId>





<version>

1.5.9. RELEASE

</version>





</parent>








<dependencies>





<dependency>





<groupId>

junit

</groupId>





<artifactId>

junit

</artifactId>





<version>

3.8.1

</version>





<scope>

test

</scope>





</dependency>




<! – servlet3.1
Specification – >



<dependency>





<groupId>

javax.servlet

</groupId>





<artifactId>

javax.servlet-api

</artifactId>





<version>

3.1.0

</version>





</dependency>





<dependency>





<groupId>

org.glassfish.web

</groupId>





<artifactId>

jsp

</artifactId>





<version>

2.2

</version>





</dependency>




<! — https://mvnrepository.com/artifact/javax.websocket/javax.websocket-api


websocket
Rely on


–>



<dependency>





<groupId>

javax.websocket

</groupId>





<artifactId>

javax.websocket-api

</artifactId>





<version>

1.1

</version>





<scope>

provided

</scope>





</dependency>




<! —
For handling JSON
Data – >



<dependency>





<groupId>

net.sf.json-lib

</groupId>





<artifactId>

json-lib

</artifactId>





<version>

2.4

</version>





</dependency>





<dependency>





<groupId>

org.springframework.boot

</groupId>





<artifactId>

spring-boot-starter-web

</artifactId>





<exclusions>





<exclusion>





<groupId>

org.springframework.boot

</groupId>





<artifactId>

spring-boot-starter-tomcat

</artifactId>





</exclusion>





</exclusions>





</dependency>




<! — https://mvnrepository.com/artifact/org.springframework/spring-websocket


spring
Integrating the websocket


–>



<dependency>





<groupId>

org.springframework

</groupId>





<artifactId>

spring-websocket

</artifactId>





</dependency>




<! –springboot
Required dependency packages –>



<dependency>





<groupId>

ch.qos.logback

</groupId>





<artifactId>

logback-core

</artifactId>





</dependency>





<dependency>





<groupId>

ch.qos.logback

</groupId>





<artifactId>

logback-classic

</artifactId>





</dependency>





</dependencies>





<build>





<finalName>

websocketspring

</finalName>








<plugins>





<plugin>





<groupId>

org.springframework.boot

</groupId>





<artifactId>

spring-boot-maven-plugin

</artifactId>





</plugin>





</plugins>





</build>

1.2 WebSocket Configuration file

Used to launch webSocket, inject handler, and interceptor

/ * *


*
Created by jackiechan on
2018/2/5 /
In the afternoon
4:05 p.m.


* /


@Configuration
//
Declare as a configuration file


@EnableWebSocket
//
To enable the websocket



public


class

WebSocketConfig

implements

WebSocketConfigurer {


@Override



public

void
registerWebSocketHandlers
(WebSocketHandlerRegistry webSocketHandlerRegistry) {


System
.
out
.
println
(
Initialize path interception
);
//
Specify all/websockets
The initial path will be websocket
Interception,
Set up the handler and interceptor


webSocketHandlerRegistry.
addHandler
(
chatMessageHandler
(),
“/websocket/*”
).
addInterceptors
(

new

ChatHandshakeInterceptor
());


}





/ * *


*
Create handler


* @
return


* /


@Bean



public

TextWebSocketHandler
chatMessageHandler
() {


System
.
out
.
println
(
create
handler”
);



return


new

ChatMessageHandler
(a);


}


}


1.3 ChatHandshakeInterceptor

It is used to intercept each Websocket before the handshake and can be verified internally


/ * *


*
Created by jackiechan on
2018/2/5 /
In the afternoon
Season,


*


*
WebSocket
Handshake request interceptor
.
Check the handshake request and response
.
right
WebSocketHandler
Passing attributes


* /



public


class

ChatHandshakeInterceptor

extends

HttpSessionHandshakeInterceptor {


/ * *


*
The method is executed before the handshake
.
Continue to shake hands and return
true
.
Interrupted handshake return
false
.
through
attributes
Parameter Settings
WebSocketSession
The properties of the


*

@param request




*

@param response




*

@param wsHandler




*

@param attributes




*
@
return


*

@throws Exception




* /


@Override



public

boolean
beforeHandshake
(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,


Map
<
String
.
Object
> attributes)

throws

Exception
{


//
To make it easier to distinguish sources,
I’m going to distinguish it by the user’s name,
The name is passed by asking for input,
So here we get the name that the user entered from the request,
Because rest is used
Style,
So the last string in the specified path is the name


System
.
out
.
println
(
Before shaking hands
);


String
s = request.
getURI
().
toString
(a);


String
s1 = s.
substring
(s.
lastIndexOf
(
“/”
) +
1
);


attributes.
put
(Constants.
WEBSOCKET_USERNAME
, s1);
//
Sets properties for the current connection






return


super

.
beforeHandshake
(request, response, wsHandler, attributes);


}





/ * *


*
The method is executed after the handshake
.
Whether the handshake was successful or not indicates the response status code and the corresponding header
.


*

@param request




*

@param response




*

@param wsHandler




*

@param ex




* /


@Override



public

void
afterHandshake
(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,


Exception
ex) {


System
.
out
.
println
(
“After Handshake”
);



super

.
afterHandshake
(request, response, wsHandler, ex);


}





}



1.4 ChatMessageHandler Message handler

Used to process messages when they are received


/ * *


*
Created by jackiechan on
2018/2/5 /
In the afternoon
4:11


*
Processor for text messages


* /



public


class

ChatMessageHandler

extends

TextWebSocketHandler {






private

static
final
Map
<
String
,WebSocketSession> allClients;
//
Used to cache all relationships between users and connections



private

static
Logger
logger =
Logger
.
getLogger
(ChatMessageHandler.
class
);





static
{


allClients =

new

ConcurrentHashMap
(a);
//
Initializing a connection


}





/ * *


*
This method is called when a connection is successfully established with the user
.
The connection should be saved inside this method


* /


@Override



public

void
afterConnectionEstablished
(WebSocketSession session)

throws

Exception
{


System
.
out
.
println
(
The connection is established successfully.
);


String
name = (
String
) session.
getAttributes
().
get
(Constants.
WEBSOCKET_USERNAME
);
//
Retrieve the name of the user saved in the interceptor,
And then as a key
To the map
In the



if

(name ! =

null

) {


allClients.
put
(name, session);
//
Saves the relationship between the current connection and the user


}


//
This will implement its own business, such as pushing offline messages to users when they log in





}





/ * *


*
This method is triggered when a message is received


*

@param session

Of the user who sent the message
session


*

@param message

Content sent


*

@throws Exception




* /


@Override



protected

void
handleTextMessage
(WebSocketSession session, TextMessage message)

throws

Exception
{


//
Perform this operation based on your service logic


JSONObject jsonObject= JSONObject.
fromObject
(

new

String
(message.
asBytes
()));
//
Convert the message sent by the user into JSON,
In actual development, please handle it according to your own requirements


String
toName = jsonObject.
getString
(
“toName”
);
//
Gets the name of the recipient in the data


String
content = jsonObject.
getString
(
“content”
);
//
Get the sent content


String
fromName = (
String
) session.
getAttributes
().
get
(Constants.
WEBSOCKET_USERNAME
);
//
Gets the name of the person currently sending the message


content =
Received from
:”
+fromName+
The news of the
.
The content is
:”
+ content;


//
Concatenate the content and forward it to the recipient,
In actual development, please refer to your own requirements


TextMessage textMessage =

new

TextMessage
(content);
//
Convert the content to a TextMessage


sendMessageToUser
(toName,textMessage);
//
To the specified user


//sendMessageToUsers(message); //
Send it to everyone


//super.handleTextMessage(session, message);


}





/ * *


*
Send a message to a user


*


*

@param userName




*

@param message




* /



public

void
sendMessageToUser
(
String
userName, TextMessage message) {


WebSocketSession webSocketSession = allClients.
get
(userName);
//
Find the connection based on the receiver’s name



if

(webSocketSession ! =

null

&& webSocketSession.
isOpen
()) {
//
If it’s not offline,
If it’s offline,
Handle the problem based on actual service requirements.
You may need to save offline messages



try

{


webSocketSession.
sendMessage
(message);
//
Send a message


}

catch

(
IOException
e) {


e.
printStackTrace
(a);


}


}


}





/ * *


*
Send messages to all online users
.
Here is an example of a text message


*


*

@param message




* /



public

void
sendMessageToUsers
(TextMessage message) {



for

(
Map
.
Entry
<
String
, WebSocketSession> webSocketSessionEntry : allClients.
entrySet
()) {
//
Get all connections





WebSocketSession session = webSocketSessionEntry.
getValue
(a);
//
Find each connection



if

(session ! =

null

&& session.
isOpen
()) {



try

{


session.
sendMessage
(message);


}

catch

(
IOException
e) {


e.
printStackTrace
(a);


}


}


}


}





/ * *


*
When something goes wrong


*

@param session




*

@param exception




*

@throws Exception




* /


@Override



public

void
handleTransportError
(WebSocketSession session,
Throwable
exception)

throws

Exception
{


String
name = (
String
) session.
getAttributes
().
get
(Constants.
WEBSOCKET_USERNAME
);



if

(session.
isOpen
()) {


session.
close
(a);


}


logger.
debug
(
Connection is closed
);


allClients.
remove
(name);
//
Remove the connection


}





/ * *


*
After the connection is closed


*

@param session




*

@param closeStatus




*

@throws Exception




* /


@Override



public

void
afterConnectionClosed
(WebSocketSession session, CloseStatus closeStatus)

throws

Exception
{


logger.
debug
(
Connection is closed
);


String
name = (
String
) session.
getAttributes
().
get
(Constants.
WEBSOCKET_USERNAME
);
//
Find the connection for the user


allClients.
remove
(name);
//
remove


}





@Override



public

boolean
supportsPartialMessages
() {



return


false

;


}





}

1.5 Springboot Boot class

Note that this class is best placed under the root package


/ * *


*
Created by jackiechan on
2018/2/5 /
In the afternoon
there


* /


@SpringBootApplication


@Configuration



public


class

App {



public

static
void
main
(
String
[] args) {


SpringApplication.
run
(App.
class
, args);
// spingboot }


}


}


1.6 Configuration classes of the Web Boot Option


/ * *


*
Created by jackiechan on
2018/2/5 /
In the afternoon
there


Used to package projects into
war
After the package release


* /



public


class

SpringBootStartApplication

extends

SpringBootServletInitializer {


@Override



protected

SpringApplicationBuilder
configure
(SpringApplicationBuilder builder)


{



return

builder.
sources
(App.
class
);


}


}


1.7 HTML

This parameter is consistent with non-Springboot

html
>



<html

lang=
“en”

>





<head>





<meta

charset=
“UTF-8”

>





<title>

Title

</title>





<script

type=
“text/javascript”

>





var

websocket
=

null

;



function

abc
(a)
{





//var username = localStorage.getItem(“name”);



var

username
=
document
.
getElementById
(
“me”
).
value
;


//
Check whether the current browser supports WebSocket



if

(
‘WebSocket’

in

window)
{


websocket
=

new

WebSocket
(
“ws://”
+
document
.
location
.
host
+
“/websocket/”
+
username)
;


}

else

{


alert
(
Current Browser
Not support websocket’
)


}





//
Connection error callback method


websocket
.
onerror
=

function

(a)
{


setMessageInnerHTML
(
“WebSocket
Connection error
)
;


};





//
Callback method for successfully establishing the connection


websocket
.
onopen
=

function

(a)
{


setMessageInnerHTML
(
“WebSocket
The connection is successful
)
;


}





//
The callback method that received the message


websocket
.
onmessage
=

function

(event)
{


setMessageInnerHTML
(
event
.
data
)
;


}





//
Connection closed callback method


websocket
.
onclose
=

function

(a)
{


setMessageInnerHTML
(
“WebSocket
Connection is closed
)
;


}





//
Listen for window closing events and actively close webSocket when the window is closed
Connect to prevent the window from closing before the connection is disconnected, server
The end throws an exception.


window
.
onbeforeunload
=

function

(a)
{


closeWebSocket
(a)
;


}


}





/ * *


*
Send a message


* /



function

sendmessage
(a)
{



var

toName
=
document
.
getElementById
(
“to”
).
value
;



if

(websocket
! =

null

)
{



var

content
=
document
.
getElementById
(
“content”
).
value
;






var

message
=
‘{“toName”:”‘
+
toName
+
‘”,”content”:”‘
+
content
+
‘”}’
;
//
Concatenate the sent content into JSON
String,
The server is used for parsing good processing


websocket
.
send
(message)
;


}


}





//
Close the WebSocket
The connection



function

closeWebSocket
(a)
{



if

(websocket
! =

null

)
{





websocket
.
close
(a)
;


}


}



function

setMessageInnerHTML
(data)
{


document
.
getElementById
(
“neirong”
).
innerHTML
=
data
;


}



</script>





</head>





<body>




The user name
:

<input

type=
“text”
id=
“me”

/>


<button

onclick=
“abc()”

>

The connection

</button><br>




<! —
The actual recipient should be chosen by the user,
Or arranged by the system,
Like customer service,
The server has stored all online customer service.
All the user has to do is send a message,
If two users are chatting,
There should be a list of users,
Select and specify target –>


The receiver
:

<input

type=
“text”
id=
“to”

/><br>




content
:

<input

type=
“text”
id=
“content”

/><br>





<button

onclick=
“sendmessage()”

>

send

</button><br>





<br>





<br>





<br>





<span

id=
“neirong”

></span>





</body>





</html>


1.8 Starting tests