Pipeline-based Instant messaging (Java NIO)

Source: Internet
Author: User
Tags addall getmessage

The implementation principle of this projectsevice only sends data to the pipeline (the data pool), waits for the data in the pool, and it automatically comes to you. You don't have to care about how data is sent and received, just focus on the processing of your business. as

Advantages:The pipeline-based implementation is that the message is sent or received only to be sent to the pipeline or read from the pipeline, without concern about how to send through the Channer, which enables the service layer and the socket decoupling. depending on the broadcast instead of relying on the callback function, the asynchronous non-blocking with NiO really implements the thread's 0 wait. Disadvantages:the data sent is difficult to implement by dropping the function (or not at all) and can only be achieved by broadcasting.
Related class IntroductionClientmessagepool,servicemessagepool Pipeline (data pool)The internal implementation principle is a list queue, the increase of data read in the corresponding queue of the press in the queue, read the queue header elements
seviceThe business logic processing class must implement the Imessagesevice interface and register with MessageobserverMessageobserver
inside there is a imessagesevice list, saving each service that implements Imessagesevice interface, and sevice constitute the observer pattern,there will be a thread dedicated to monitoring the Messagepool, and once you have the data, give it to messageobserver. The messageobserver is sent to the established service according to the specific message analogy.Socketchannel
Implements a Sockenchannel class, which is equivalent to a client. Reads data from the pipeline (Clientmessagepool) and writes the data to the pipeline once it has dataSelectorreceive pipeline registration, and root conditions, to the specified Socketchannel drive data. The data is also filtered according to the filter criteria. Code ImplementationPipeline Code Implementation
Package Com.pool;import Java.util.queue;import Java.util.concurrent.linkedblockingqueue;public class MessagePool { public static queue<string> Clintmessagequeue = new linkedblockingqueue<string> (); public static queue<string> Servermessagequeue = new linkedblockingqueue<string> (); }
Interface
Package Com.pool;public interface Imessagepool {public void AddMessage (String message);p ublic String pollmessage (); public boolean isEmpty ();}


Implementation class
Package Com.pool.impl;import Com.pool.imessagepool;import Com.pool.messagepool;public class ClientMessagePool Implements Imessagepool {@Overridepublic  void AddMessage (String message) {MessagePool.clintmessageQueue.add ( message);} @Overridepublic  String pollmessage () {return MessagePool.clintmessageQueue.poll ();} @Overridepublic Boolean isEmpty () {if (MessagePool.clintmessageQueue.size () >0) return True;elsereturn false;}}

Client
Package Com.socket;import Java.io.ioexception;import Java.net.inetsocketaddress;import java.nio.ByteBuffer;import Java.nio.channels.selectionkey;import Java.nio.channels.selector;import Java.nio.channels.socketchannel;import Java.util.iterator;import Org.apache.commons.lang.arrayutils;import Com.pool.imessagepool;import Com.pool.impl.clientmessagepool;import Com.util.packageutil;public class Mysocket {private Socketchannel Msocketchannel;private selectionkey key;public static string CHARSET = "Utf-8";p ublic static string ADDRESS = "127.0.0.1"; public static int HOST = 34521;protected Selector mselector;protected imessagepool messagepool = new Clientmessagepool ();; Bytebuffer buffer;public Mysocket () {try {mselector = Selector.open (); Initsocketchannel (); initbassiness ();} catch ( Exception e) {e.printstacktrace ();} finally {try {Key.channel (). Close ();} catch (IOException e) {e.printstacktrace ()}}} /** * Business logic * * @throws Exception */private void Initbassiness () throws Exception {while (true) {checkwriteable ();//instantaneous detection if (Mselector.select > 0) {iterator<selectionkey> keys = Mselector.selectedkeys (). iterator (); while (Keys.hasnext ()) {Selectionkey key = Keys.next (); if (Key.isreadable ()) { Dispose4readable (key);} if (Key.isvalid () && key.iswritable ()) {dispose4writable (key);} Keys.remove ();}}} /** * Readable Request * * @param key * @throws Exception */protected void dispose4readable (Selectionkey key) throws Exception {Socke TChannel Msocketchannel = ((Socketchannel) Key.channel ()), buffer = Bytebuffer.allocate (1024x768); Msocketchannel.read ( buffer); Buffer.flip (); This.unpacket (Buffer.array (), key);} /** * Writable Request * * @param key * @throws Exception */protected void dispose4writable (Selectionkey key) throws Exception {Socke TChannel Msocketchannel = ((Socketchannel) Key.channel ()); int value = 0;do{value = msocketchannel.write (buffer);} while (value!=0); Key.interestops (Key.interestops () & ~selectionkey.op_write); Key.interestops (SelectionKey.OP_ READ);} /** * Unpacking * * @param buf * @rEturn */public byte[] Unpacket (byte[] buf, Selectionkey key) {int len = buf.length;//37int i;for (i = 0; i < len; i++) {if (Len < i + packageutil.packageheaderlength+ packageutil.packagesavedatalength) {break;} string tmp = new String (Arrayutils.subarray (buf, I, i+ packageutil.packageheaderlength)), if (Tmp.equals ( Packageutil.packageheader)) {int messagelength = Packageutil.byte2int (Arrayutils.subarray (buf, i + Packageutil.packageheaderlength, i+ packageutil.packageheaderlength+ packageutil.packagesavedatalength)); if (len < i + packageutil.packageheaderlength+ Packageutil.packagesavedatalength + messagelength) {break;} byte[] data = Arrayutils.subarray (buf, i+ packageutil.packageheaderlength+ packageutil.packagesavedatalength, i+ packageutil.packageheaderlength+ packageutil.packagesavedatalength + messagelength); String message = new string (data); SYSTEM.OUT.PRINTLN (message);//filter.filterread (message, key, messagepool); i + = packageutil.packageheaderlength+ Packageutil.packagesavEdatalength + messageLength-1;}} if (i = = len) {return new byte[0];} Return Arrayutils.subarray (buf, I, buf.length);} void Initsocketchannel () throws Exception {Msocketchannel = Socketchannel.open (); Msocketchannel.connect (new Inetsocketaddress (ADDRESS, HOST)); msocketchannel.configureblocking (false); key = Msocketchannel.register (mselector , selectionkey.op_connect| Selectionkey.op_read);} void Checkwriteable () {if (Messagepool.isempty ()) {String values = Messagepool.pollmessage (); System.out.println ("" +values); buffer = Bytebuffer.wrap (Packageutil.packet (values.getbyt ES ())); Key.interestops (Selectionkey.op_write);}}}

Server
Package Com.socket;import Java.io.ioexception;import Java.net.inetsocketaddress;import java.nio.ByteBuffer;import Java.nio.channels.selectionkey;import Java.nio.channels.selector;import Java.nio.channels.ServerSocketChannel; Import Java.nio.channels.socketchannel;import Java.util.iterator;import Java.util.set;import Org.apache.commons.lang.arrayutils;import Com.filter.filter;import Com.pool.imessagepool;import Com.pool.impl.servermessagepoll;import Com.util.packageutil;public class myServerSocket {private Serversocketchannel mserversocketchannel;private static myserversocket serversocket;public static String CHARSET = " Utf-8 ";p ublic static String ADDRESS =" 127.0.0.1 ";p ublic static int HOST = 34521;protected Selector mselector;protected IM Essagepool Messagepool = new Servermessagepoll (); Bytebuffer buffer;private myServerSocket () throws Exception {try {mselector = Selector.open (); Initsocketchannel (); Initbassiness ();} catch (Exception e) {e.printstacktrace ();} finally {Set<selectionkey> keys = Mselector.keys (); {for (Selectionkey Key:keys) {try {Key.channel (). Close ()} catch (IOException e) {e.printstacktrace (); continue;}}}} /** * Business logic * * @throws Exception */private void Initbassiness () throws Exception {while (true) {checkwriteable ();//instantaneous detection I F (mselector.select () > 0) {iterator<selectionkey> keys = Mselector.selectedkeys (). Iterator (); while ( Keys.hasnext ()) {Selectionkey key = Keys.next (); if (Key.isacceptable ()) {dispose4acceptable (key);} if (key.isreadable ()) {dispose4readable (key);} if (Key.isvalid () && key.iswritable ()) {dispose4writable (key);} Keys.remove ();}}} /** * Response Read * @param key * @throws Exception */protected void dispose4readable (Selectionkey key) throws Exception {Socketcha Nnel Msocketchannel = ((Socketchannel) Key.channel ()), buffer = Bytebuffer.allocate (1024x768), Msocketchannel.read (buffer) ; Buffer.flip (); This.unpacket (Buffer.array (), key);} /** * Writable Request * * @param key * @throws Exception */protected void dispose4writable (Selectionkey key) Throws Exception {Socketchannel Msocketchannel = ((Socketchannel) Key.channel ()); if (msocketchannel.write (buffer)!=-1 ) {buffer.clear ();} Key.interestops (Key.interestops () & ~selectionkey.op_write);//key.interestops (Selectionkey.op_read);} /** * Unpacking * * @param buf * @return */private byte[] Unpacket (byte[] buf, Selectionkey key) {int len = buf.length;//37int I;for (i = 0; i < len; i++) {if (Len < i + packageutil.packageheaderlength+ packageutil.packagesavedatalength) {Brea K;} string tmp = new String (Arrayutils.subarray (buf, I, i+ packageutil.packageheaderlength)), if (Tmp.equals ( Packageutil.packageheader)) {int messagelength = Packageutil.byte2int (Arrayutils.subarray (buf, i + Packageutil.packageheaderlength, i+ packageutil.packageheaderlength+ packageutil.packagesavedatalength)); if (len < i + packageutil.packageheaderlength+ Packageutil.packagesavedatalength + messagelength) {break;} byte[] data = Arrayutils.subarray (buf, i+ packageutil.packageheaderlength+ Packageutil.packagesaVedatalength, i+ packageutil.packageheaderlength+ packageutil.packagesavedatalength + messageLength); String message = new string (data); SYSTEM.OUT.PRINTLN ("server Read message" + message); Filter.filterread (Message, key, messagepool); i + = packageutil.packageheaderlength+ Packageutil.packagesavedatalength + messageLength-1;}} if (i = = len) {return new byte[0];} Return Arrayutils.subarray (buf, I, buf.length);} public static myServerSocket Newinstence () throws Exception {if (ServerSocket = = null) {return new myServerSocket ();} return serversocket;} /** * Socketchannel initialization * @throws Exception */void Initsocketchannel () throws Exception {Mserversocketchannel = Serversocke Tchannel.open (); mserversocketchannel.configureblocking (false); Mserversocketchannel.bind (New InetSocketAddress ( ADDRESS, HOST)); Mserversocketchannel.register (Mselector, selectionkey.op_accept);} void Dispose4acceptable (Selectionkey key) throws Exception {Socketchannel Msocketchannel = ((Serversocketchannel) Key.channel ()). Accept (); mSocketchannel.configureblocking (false); Msocketchannel.register (Mselector, selectionkey.op_read);} void Checkwriteable () {if (Messagepool.isempty ()) {String value = Messagepool.pollmessage ();  String result = Filter.filterwrite (value, Mselector), if (result! = null) {System.out.println ("server:" + result); Bytebuffer.wrap (Packageutil.packet (Result.getbytes ()));}}}

Filter filters
Package Com.filter;import Java.nio.channels.selectionkey;import Java.nio.channels.selector;import java.util.Set; Import Com.model.basemodule;import com.model.chat;import Com.model.user;import Com.pool.imessagepool;import  Com.util.stringutil;public class Filter {private static final String login = "Login";p rivate static basemodule Modul = new Basemodule ();p rivate static selectionkey selectionkey=null;private static Selector Selector = null;/** * TODO Thread Start * * @ Param message * @return */public static void Filterread (String message, Selectionkey key,imessagepool messagepool) {Select Ionkey = key;try {basemodule Filtermodul = (basemodule) Stringutil.string2bean (modul,message); if (FilterType ( Filtermodul.gettype ())) {if (FilterValue (Filtermodul.getmessage ())) {//messagepool.addmessage (message);} Else{}}else{messagepool.addmessage (message);}} catch (Exception e) {return;}} public static string Filterwrite (String Message,selector mselector) {Selector = Mselector;return filter (message);} private staticString filter (String message) {Basemodule Filtermodul = (basemodule) Stringutil.string2bean (modul,message); Chat chat = (chat) stringutil.string2bean (new Chat (), filtermodul.getmessage ()); Set<selectionkey> Keys=selector.keys (); for (Selectionkey Key:keys) {String markstring=key.attachment ()!=null? Key.attachment (). toString (): Null;if (markstring!=null && markstring.equals (Chat.getto ())) {Key.interestops (selectionkey.op_write); return Chat.getmessage ();}} return null;} /** * Filter Type * @param value * @return */private static Boolean FilterType (String value) {if (Login.equals (value)) {return TR UE;} return false;} /** * Filter Contents * @param value * @return */private static Boolean FilterValue (String value) {return Filterlogin (value);} private static Boolean Filterlogin (String value) {User user = (user) Stringutil.string2bean (new User (), value); if (user.ge Tusername ()! = null) {Selectionkey.attach (User.getusername ()); return true;} return false;}}


Service Interface
Package Com.service;public interface Imessageservice {void domessage (String message);
Util
Package Com.util;import Java.io.unsupportedencodingexception;import Org.apache.commons.lang.arrayutils;public Class PackageUtil {public static final String Packageheader = "?-?";  /Message length public static final int packageheaderlength = 7; Data head length?? public static final int packagesavedatalength = 4; Number of bits in the data length station/** * Package * @param pkg to package byte array * @return */public static byte[] Packet (byte[] pkg) {int intvalue = Pkg.length;by Te[] B = new Byte[4];for (int i = 0; i < 4; i++) {B[i] = (byte) (Intvalue >> 8 * (3-i) & 0xFF);//System.ou T.print (Integer.tobinarystring (b[i]) + "")//system.out.println ((B[i] & 0xFF) + ""); try {byte[] newpkg = Arrayutils.addall (PackageUtil.PACKAGEHEADER.getBytes ("Utf-8"), b); newpkg = Arrayutils.addall ( Newpkg, pkg); return newpkg;} catch (Unsupportedencodingexception e) {e.printstacktrace ();} return null;} /** * byte array goto * @param b * @return */public static int byte2int (byte[] b) {int intvalue = 0;for (int i = 0; i < B.lengt H i++) {intvalue + = (B[i] & 0xFF) << (8 * (3-i));//System.out.print (integer.tobinarystring (intvalue) + "");} return intvalue;} /** * @param args */public static void main (string[] args) {//TODO auto-generated method stub}}


Stringutil
Package Com.util;import Com.google.gson.gson;public class Stringutil {private static Gson json =new Gson ();/** * string specifically for JSO n * @param clazz * @param message * @return */public static object String2bean (object clazz,string message) {return json.fr Omjson (Message, Clazz.getclass ());} /** * JSON specifically for string * @param clazz * @return */public static string Bean2json (Object clazz) {return Json.tojson (clazz);}}

Module
Package com.model;/** * Default packaging * @author Administrator * */public class Basemodule {String type; String Message;public string GetType () {return type;} public void SetType (String type) {this.type = type;} Public String GetMessage () {return message;} public void Setmessage (String message) {this.message = message;}}

this is a prototype. This will be followed by the implementation of specific details and the rationale for the explanation

Pipeline-based Instant messaging (Java NIO)

Related Article

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.