Today is a very bad mood!!! The reason is confidential.
This article is based on the "Netty and WebSocket communication demo".
Bad idea: A large number of customer requests, a common worker, to achieve push.
Correct practice: should be the channel corresponding to the channelgroup operation, to achieve push.
A channel can be divided into multiple channelgroup.
Pushserverchannelhandler and Dynmessage These two classes are the most important, in fact, the class basically unchanged.
package org.sl.demo.chatserver;import java.util.list;import java.util.map;import org.jboss.netty.buffer.channelbuffers;import org.jboss.netty.channel.channel;import Org.jboss.netty.channel.channelhandlercontext;import org.jboss.netty.channel.channelstateevent;import org.jboss.netty.channel.ExceptionEvent;import org.jboss.netty.channel.MessageEvent;import Org.jboss.netty.channel.simplechannelhandler;import org.jboss.netty.channel.group.channelgroup;import org.jboss.netty.channel.group.DefaultChannelGroup;import org.jboss.netty.handler.codec.http.defaulthttpresponse;import org.jboss.netty.handler.codec.http.httpheaders;import org.jboss.netty.handler.codec.http.httpmethod; import org.jboss.netty.handler.codec.http.httprequest;import org.jboss.netty.handler.codec.http.httpresponsestatus;import Org.jboss.netty.handler.codec.http.httpversion;import org.jboss.netty.handler.codec.http.websocketx.closewebsocketframe;import org.jboss.netty.handler.codec.http.websocketx.pingwebsocketframe;import org.jboss.netty.handler.codec.http.websocketx.pongwebsocketframe;import org.jboss.netty.handler.codec.http.websocketx.textwebsocketframe;import org.jboss.netty.handler.codec.http.websocketx.websocketframe;import org.jboss.netty.handler.codec.http.websocketx.websocketserverhandshaker;import org.jboss.netty.handler.codec.http.websocketx.websocketserverhandshakerfactory;public class pushserverchannelhandler extends simplechannelhandler {static boolean debug = true; @Overridepublic void channelopen (channelhandlercontext ctx, channelstateevent e) {if (debug) {System.out.println ("Channelopen");} Dynmessage.addaudience (E.getchannel ());} @Override public void messagereceived (channelhandlercontext ctx, Messageevent e) &NBSP;THROWS&NBSP;EXCEPTION{CHANNEL&NBSP;CH&NBSp;= e.getchannel (); Object msg = e.getmessage (); if (Debug) {System.out.println ("------------ ---"); System.out.println ("message: " +msg.getclass ());} Try{if (msg instanceof httprequest) {processhttprequest (ch, (HttpRequest) msg);} Else if (msg instanceof websocketframe) {processwebsocketrequest (ch, (websocketframe) msg);} else{//the unhandled request type}}catch (Exception ex) {ch.close (). sync (); Super.messagereceived (ctx, e);} @Overridepublic void channelclosed (channelhandlercontext ctx, channelstateevent e) {if (Debug) {System.out.println ("channelclosed");} if (e instanceof messageevent) {messageevent me = (messageevent) e;} Dynmessage.removeaudience (E.getchannel ()); E.getchannel (). Close (); @Overridepublic void exceptioncaught (channelhandlercontext ctx, exceptionevent e) {if ( Debug) {System.out.println ("channelclosed");} Dynmessage.removeaudience (E.getchannel ()); E.getcause (). PrintstacktraCE (); E.getchannel (). Close (); Try {super.exceptioncaught (ctx, e);} catch (EXCEPTION&NBSP;E1) {e1.printstacktrace ();}} Void processhttprequest (channel channel,httprequest request) {httpheaders headers = request.headers (); if (debug) {list<map.entry<string,string>> ls = Headers.entries (); for (Map.entry<string,string> i: ls) {System.out.println ("header " + I.getkey () + ":" +i.getvalue ());}} Non-get requestif (! HttpMethod.GET.equals (Request.getmethod ())) {defaulthttpresponse resp = new Defaulthttpresponse (httpversion.http_1_1,httpresponsestatus.bad_request); Channel.write (resp); Channel.close (); return;} Websocketserverhandshakerfactory wsshakerfactory = new websocketserverhandshakerfactory (" ws://"+request.headers (). Get (HttpHeaders.Names.HOST),null,false ); Websocketserverhandshaker wsshakerhandler = wsshakerfactory.newhandshaker (Request)if (Null==wsshakerhandler) {//Cannot process WebSocket version wsshakerfactory.sendunsupportedwebsocketversionresponse (channel);} else{//sends the WebSocket handshake to the client, completes the handshake//The client receives a status of 101 sitching protocolwsshakerhandler.handshake (channel, request);}} Void processwebsocketrequest (channel channel, websocketframe request) throws Exception{if (request instanceof closewebsocketframe) {dynmessage.removeaudience (channel); Channel.close (). sync ();} Else if (request instanceof pingwebsocketframe) {Channel.write (New pongwebsocketframe ( Request.getbinarydata ())); }else if (request instanceof textwebsocketframe) {//This place can add some business logic textwebsocketframe txtreq = (textwebsocketframe) request;if (Debug) as required. system.out.println ("Txtreq:" +txtreq.gettext ());} if ("Disconnect". Equalsignorecase (Txtreq.gettext ())) {dynmessage.removeaudience (channel); Channel.close (). sync (); return;} Add the eligible channel to the Channelgroup of the Dynmessage DynmeSsage.addaudience (channel);} Else{//websocketframe and some}}}
package org.sl.demo.chatserver;import java.util.random;import org.jboss.netty.buffer.channelbuffers;import org.jboss.netty.channel.channel;import org.jboss.netty.channel.group.channelgroup;import org.jboss.netty.channel.group.defaultchannelgroup; The import org.jboss.netty.handler.codec.http.websocketx.textwebsocketframe;/*** dynamically generates the message and pushes it to the channel group. */public class dynmessage implements runnable{public static channelgroup Audiences = new defaultchannelgroup ("Msg-group"); Static public void addaudience ( Channel ch) {audiences.add (ch);} Static public void removeaudience (channel ch) {audiences.remove (ch);} static string[] names = {"Tom", "Jerry", "Terry", "Looney", "Merrie", " William "," Joseph ", " Hanna "," Speike ", " Tyke "," Tuffy ", " Lightning ",};static string message = "";p ublic static string getmessage (){Stringbuffer sb = new stringbuffer (); Sb.append ("hello,my name is "); Sb.append (Names[new random () nextint (names.length)); Sb.append ("."); Return sb.tostring ();//return message;} @Overridepublic void run () {system.out.println ("Dynmessage start"); for (;;) {string msg = getmessage (); Radiate (msg); Try{thread.sleep (+); }catch (Exception ex) { }}}void radiate (string msg) {Audiences.write (New textwebsocketframe (msg));}}
Var _mp_ws = null;var _mp_ajax_it = null;function msgpush (Url, params, Onmessage,onclose,onerror) {Wsmsgpush (Url,params,onmessage,onclose,onerror), if (!_MP_WS) {AjaxMsgPush (Url,params, 10000,onmessage,onclose,onerror);}} Function old_wsmsgpush (Url, params,onmessage,onclose,onerror) {var ws = new WebSocket ("ws://" +url); ws.onopen = function () {ws.send (' 1111 ')};ws.onmessage = function (evt) { onmessage (evt.data);};} Function wsmsgpush (url, params,onmessage,onclose,onerror) {_mp_ws = new websocket ("ws ://"+url"); if (!_MP_WS) { return; }_mp_ws.onopen = function () { _mp_ws.send (params) ; };if (OnMessage) _mp_ws.onmessage = function (evt) { onmessage (evt.data); }if ( onerror) _mp_ws.onerror = function (evt) { onerror (); }if (OnClose) _mp_ ws.onclose = function (evt) { onclose (); &nbSP;}} Function ajaxmsgpush (url, params,interval,onmessage,onclose,onerror) {function __getmsg () {$.ajax ({url:url,data:params,cache:true,type: "Get", DataType: "Text", Success:function (data, textstatus, jqxhr { if (onmessage) onmessage (data);},error:function (Jqxhr, textstatus, errorthrown) {if ( onerror) onerror ();},complete:function (jqxhr, textstatus) {if (OnClose) onclose ();}}); _mp_ajax_it = setinterval ("__getmsg ()", interval);} Function stopmsgpush () {if (_MP_WS) {_mp_ws.send ("disconnect"); _mp_ws.close ();} if (_mp_ajax_it) {clearinterval (_mp_ajax_it);}} var chars = [' 0 ', ' 1 ', ' 2 ', ' 3 ', ' 4 ', ' 5 ', ' 6 ', ' 7 ', ' 8 ', ' 9 ', ' A ', ' B ', ' C ', ' D ', ' E ', ' F ', ' G ', ' H ', ' I ', ' J ', ' K ' ', ' L ', ' M ', ' N ', ' O ', ' P ', ' Q ', ' R ', ' S ', ' T ', ' U ', ' V ', ' W ', ' X ', ' Y ', ' Z '];function generatemixed (n) { var res = ""; for (var i = 0 ; i < n ; i ++) &NBSP;{&NBSp; var id = math.ceil (Math.random () *35); res += chars[id]; } return res;}
package org.sl.demo.chatserver;import org.jboss.netty.channel.channelpipeline;import org.jboss.netty.channel.channelpipelinefactory;import org.jboss.netty.channel.channels;import org.jboss.netty.handler.codec.http.httprequestdecoder;import org.jboss.netty.handler.codec.http.httpresponseencoder;import Org.jboss.netty.handler.timeout.writetimeouthandler;import org.jboss.netty.util.hashedwheeltimer;public class pushserverchannelpiplelinefactory implements channelpipelinefactory{@ Overridepublic channelpipeline getpipeline () throws Exception {ChannelPipeline Cp = channels.pipeline (); Cp.addlast ("Decoder", new httprequestdecoder ()); Cp.addLast (" Encoder ", new httpresponseencoder ()); Cp.addlast (" WriteTimeout ", new writetimeouthandler ( New hashedwheeltimer (), Cp.addlast ("handler", new pushserverchannelhandler ());return CP;}}
package org.sl.demo.chatserver;import java.net.inetsocketaddress;import java.util.concurrent.executors;import org.jboss.netty.bootstrap.serverbootstrap;import org.jboss.netty.channel.socket.nio.nioserversocketchannelfactory;public class pushserver Implements runnable{int port = 80;public pushserver (int port) {this.port = port;} @Overridepublic void run () {system.out.println ("chatserver " +port); Serverbootstrap b = new serverbootstrap (New nioserversocketchannelfactory ( Executors.newcachedthreadpool (), Executors.newcachedthreadpool ()); B.setoption ("Child.tcpnodelay", true); b.setoption ("Child.keepalive", true); B.setpipelinefactory (new Pushserverchannelpiplelinefactory ()); B.bind (New inetsocketaddress (port));} Public static void main (String[] args) {Thread t = new thread (new Dynmessage (), "Dynmessage"); T.start (); new pushserver. Run ();}}
Netty websocket Simple Message Push demo