[Java] Netty Websocket Server Javascript Client

Source: Internet
Author: User
Tags set socket

The emergence of the WebSocket protocol is undoubtedly one of the most exciting features of HTML5. It can effectively replace the Comet technology and Flash XmlSocket to implement HTTP-based bidirectional communication. Currently, mainstream browsers such as Chrome, Firefox, IE10, Opera10, and Safari all support WebSocket. In addition, some good WebSocket projects, such as Resin, Jetty7, and pywebsocket, also appeared on the server. However, this article will introduce how to use the powerful Netty framework (Netty-3.5.7.Final) to implement WebSocket server.

The performance advantages of the Netty3 framework do not need to be discussed, but what makes developers more comfortable is that Netty3 also provides a wide range of protocol implementations, including HTTP, Protobuf, and WebSocket, developers can easily implement their own Socket Server. According to the general idea of Netty3, we need to prepare the following three files:

1. WebSocketServer. java
2. WebSocketServerHandler. java
3. WebSocketServerPipelineFactory. java

The preceding three files contain the main program logic, service processing logic, and Socket Pipeline setting logic. Java code implementation is as follows:

WebSocketServer. java
[Java]
Public class WebSocketServer
{
Private final int port;
 
Public WebSocketServer (int port ){
This. port = port;
}
 
Public void run (){
// Set Socket channel factory
ServerBootstrap bootstrap = new ServerBootstrap (
New NioServerSocketChannelFactory (
Executors. newCachedThreadPool (),
Executors. newCachedThreadPool ()));
 
// Set the Socket pipeline factory
Bootstrap. setPipelineFactory (new WebSocketServerPipelineFactory ());
 
// Start the service and start listening
Bootstrap. bind (new InetSocketAddress (port ));
 
// Print the prompt information
System. out. println ("Web socket server started at port" + port + '.');
System. out. println ("Open your browser and navigate to http: // localhost:" + port + '/');
}
 
Public static void main (String [] args ){
Int port;
If (args. length> 0 ){
Port = Integer. parseInt (args [0]);
} Else {
Port = 8080;
}
New WebSocketServer (port). run ();
}
}
WebSocketServerPipelineFactory. java
[Java]
Public class WebSocketServerPipelineFactory implements ChannelPipelineFactory {
Public ChannelPipeline getPipeline () throws Exception {
// Pipeline configuration and logic
ChannelPipeline pipeline = pipeline ();
Pipeline. addLast ("decoder", new HttpRequestDecoder ());
Pipeline. addLast ("aggregator", new HttpChunkAggregator (65536 ));
Pipeline. addLast ("encoder", new HttpResponseEncoder ());
Pipeline. addLast ("handler", new WebSocketServerHandler ());
Return pipeline;
}
}
WebSocketServerHandler. java
[Java]
Public class WebSocketServerHandler extends SimpleChannelUpstreamHandler
{
Private static final InternalLogger logger = InternalLoggerFactory
. GetInstance (WebSocketServerHandler. class );
 
Private static final String WEBSOCKET_PATH = "/websocket ";
 
Private WebSocketServerHandshaker handshaker;
 
@ Override
Public void messageReceived (ChannelHandlerContext ctx, MessageEvent e)
Throws Exception {
// Process and accept messages
Object msg = e. getMessage ();
If (msg instanceof HttpRequest ){
HandleHttpRequest (ctx, (HttpRequest) msg );
} Else if (msg instanceof WebSocketFrame ){
HandleWebSocketFrame (ctx, (WebSocketFrame) msg );
}
}
 
@ Override
Public void exceptionCaught (ChannelHandlerContext ctx, ExceptionEvent e)
Throws Exception {
// Handle exceptions
E. getCause (). printStackTrace ();
E. getChannel (). close ();
}
 
Private void handleHttpRequest (ChannelHandlerContext ctx, HttpRequest req)
Throws Exception {
// Only accept http get requests
If (req. getMethod ()! = GET ){
SendHttpResponse (ctx, req, new DefaultHttpResponse (HTTP_1_1,
FORBIDDEN ));
Return;
}
 
// Start Websocket handshake
WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory (
GetWebSocketLocation (req), null, false );
Handshaker = wsFactory. newHandshaker (req );
If (handshaker = null ){
WsFactory. sendUnsupportedWebSocketVersionResponse (ctx. getChannel ());
} Else {
Handshaker. handshake (ctx. getChannel (), req). addListener (
WebSocketServerHandshaker. HANDSHAKE_LISTENER );
}
}
 
Private void handleWebSocketFrame (ChannelHandlerContext ctx,
WebSocketFrame ){
// Websocket handshake ends
If (frame instanceof CloseWebSocketFrame ){
Handshaker. close (ctx. getChannel (), (CloseWebSocketFrame) frame );
Return;
} Else if (frame instanceof PingWebSocketFrame ){
Ctx. getChannel (). write (new PongWebSocketFrame (frame. getBinaryData ()));
Return;
} Else if (! (Frame instanceof TextWebSocketFrame )){
Throw new UnsupportedOperationException (String. format ("% s frame types not supported ",
Frame. getClass (). getName ()));
}
 
// Process the received data (converted to uppercase) and return
String request = (TextWebSocketFrame) frame). getText ();
If (logger. isDebugEnabled ()){
Logger. debug (String. format ("Channel % s encoded ed % s", ctx. getChannel (). getId (), request ));
}
Ctx. getChannel (). write (new TextWebSocketFrame (request. toUpperCase ()));
}
 
Private static void sendHttpResponse (ChannelHandlerContext ctx,
HttpRequest req, HttpResponse res ){
// Return the HTTP Error Page
If (res. getStatus (). getCode ()! = 200 ){
Res. setContent (ChannelBuffers. copiedBuffer (res. getStatus (). toString (), CharsetUtil. UTF_8 ));
SetContentLength (res, res. getContent (). readableBytes ());
}
 
// Send the returned information and close the connection
ChannelFuture f = ctx. getChannel (). write (res );
If (! IsKeepAlive (req) | res. getStatus (). getCode ()! = 200 ){
F. addListener (ChannelFutureListener. CLOSE );
}
}
 
Private static String getWebSocketLocation (HttpRequest req ){
Return "ws: //" + req. getHeader (HttpHeaders. Names. HOST) + WEBSOCKET_PATH;
}
}

The logic of the above Code is clear: first, set WebSocketServerPipelineFactory in WebSocketServer; then, set WebSocketServerPipelineFactory in WebSocketServerPipelineFactory; then, process the request and return the result in WebSocketServerHandler, the most important processing logic is in the handleWebSocketFrame method, that is, to convert all the obtained request information into uppercase and return data. Finally, run WebSocketServer. java to start the WebSocket service and listen to the local port 8080. At this point, the WebSocket server is all ready. Here, we have developed a simple HTTP server with the following interface:

 

Next, we need to prepare a WebSocket client implemented by Javascript. The implementation is very simple. The Javascript code is implemented as follows:

Websocket.html
[Html]
<Html> <Body>
<Script type = "text/javascript">
Var socket;
If (! Window. WebSocket ){
Window. WebSocket = window. WebSocket;
}
// Javascript Websocket Client
If (window. WebSocket ){
Socket = new WebSocket ("ws: // localhost: 8080/websocket ");
Socket. onmessage = function (event ){
Var ta = document. getElementById ('responsetext ');
Ta. value = ta. value + '\ n' + event. data
};
Socket. onopen = function (event ){
Var ta = document. getElementById ('responsetext ');
Ta. value = "Web Socket opened! ";
};
Socket. onclose = function (event ){
Var ta = document. getElementById ('responsetext ');
Ta. value = ta. value + "Web Socket closed ";
};
} Else {
Alert ("Your browser does not support Web Socket .");
}
// Send Websocket data
Function send (message ){
If (! Window. WebSocket) {return ;}
If (socket. readyState = WebSocket. OPEN ){
Socket. send (message );
} Else {
Alert ("The socket is not open .");
}
}
</Script>
<H3> Send: <Form onsubmit = "return false;">
<Input type = "text" name = "message" value = "Hello World! "/> <Input type =" button "value =" Send Web Socket Data "onclick =" send (this. form. message. value) "/>
<H3> Receive: <Textarea id = "responseText" style = "width: 500px; height: 300px;"> </textarea>
</Form>
</Body>
</Html>

The logic of the above Javascript code is well understood: Create a Socket connection pointing to the corresponding WebSocket address (ws: // localhost: 8080/websocket), and then send and obtain the connection. In fact, we only need to place the websocket.html file on any HTTP server and open the corresponding URL address to see the following Demo interface:

 

Enter "Hello World" and click "Send Web Socket Data" to Send messages to the WebSocket server. We can also see that the returned message (uppercase hello world text) is displayed in the output box below "Receive", so that a basic information interaction is completed. Of course, if you close the server, the "Web Socket closed" information will be displayed in the output box.

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.