推送服务器

一、基本原理

长连接、短连接 长连接比如socket,短连接比如HTTP

短连接推送就是不断的客户端向服务器轮训;长连接推送就是服务器的推送(本文)

考虑的问题诸如身份鉴别认证、服务器并发量、断线重连

 

二、使用Socket和Mina框架

【Server】Server要先于Client启动

ServerSocket serverSock =  new ServerSocket("9898");

Socket socket = serverSock.accept();//block here

BufferedReader buffer = new BufferReader(new InputStreamReader(socket.getInputStream()));

String msg;

while(!msg = buffer.readLine() != null){//必须有个\n

         System.out.println()

}

//close the stream object

 

【Client】

BufferedReader inputReader;

BufferedWriter writer;

 

try{

         Socket socket = new Socket("localhost", "9898");//client socket

         writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

         inputReader = new BufferReader(new InputStreamReader(System.in));//从控制台获取字符串

         String inputContent;

         while(!(inputContent = inputReader.readLine().equals("bye"))){

                   writer.write(inputContent + "\n");//必须有个\n

                   writer.flush();

         }

}catch(Exception e){

        

}finally{

         //close stream

}

 

【客户端异步的监听服务器发送过来的消息】

匿名内部类在方法内部时,方法的参数必须要用final修饰,保证传进来的变量内外一致性

public void startServerReplyListener(final BufferedReader reader){

         new Thread(

                   new Runnable(){

                            public void run(){

                                     String response;

                                     while(response = reader.readLine() != null){//阻塞

                                               //do something

                                     }

                            }

                   }

         ).start();

}

//调用

startServerReplyListener(new BufferReader(new InputStreamReader(socket.getInputStream())));

 

Server中用while(true)来死循环接收客户的连接,同时开启新的子线程处理与客户端的交互

public void managerSock(final Socket socket){

         new Thread(

                   new Runnable(){

                            public void run(){

                                     BufferedReader buffer = new BufferReader(new InputStreamReader(socket.getInputStream()));

                                     String msg;

                                     while(!msg = buffer.readLine() != null){//必须有个\n

                                               System.out.println()

                                     }

                            }

                   }

         ).start();

}

//在主线程中

while(true){

         Socket clientSocket = Server.accept();

         managerSock(clientSocket);

}

 

若有大量客户连接的时候,因为有大量线程的创建,因为性能问题,很少会有用原生的Socket接口,同时因为是阻塞的接口,所以会有性能问题。

所以可以用NIO的框架Mina

 

【Mina初体验】

两个使用的jar包:mina-core.jar,slf4j-api.jar(打印日志用)

四步骤来创建一个Mina Server

a. new NioSocketAcceptor

b. 使用一个handler继承IoHandlerAdapter作为回话管理和消息分发机制,放到acceptor里面

c. 使用拦截器过滤来编解码,做onMessageRecieve收回的message的对象的转换工作,声明想要接受的数据类型

d. 调用acceptor的bind方法//服务器启动起来了

创建以后就可以正常接受上述普通Socket客户端的连接请求和数据发送了

 

//设置idle的定义

acceptor.getSeeionConfig().setIdleTime(IdleStatus.xxx,seconds)

这个可以定义客户端多久没有发送或者读取消息的时候为空闲状态,那么这个时候IoHandlerAdapter的onSessionIdle会回调到

这个可以用于判定是否客户端是否掉线,如果客户端一定时间没哟连接,那么这个时候服务端可以选择踢掉客户端

 

【自定义编解码】

实现ProtocolCodecFactory接口,其中复写两个方法,分别返回加解密的对象

 

【XMPP协议】

XMPP是一种以XML为基础的开放式实时通信协议,其实推送就是IM通信的“一半”

GTalk,MSN,Facebook都是支持XMPP协议

 

XMPP由于是基于XML,所以有数据冗余,在移动端会产生很多不必要的流量,但是由于推送并不频繁数据传输,所以不用考虑

同时不支持二进制数据。不过XMPP主要是关注与消息的传输

 

XMPP规定每个客户端使用JID来身份表示:[user"@"]domain["/"resource]

posted @ 2015-03-24 14:08  soaringEveryday  阅读(341)  评论(0编辑  收藏  举报