最近面试,老是被问到会不会即时通讯,导致错失了不少的公司。

1.即时通讯的原理:

  就像数学是由1+1慢慢增加难度一样,即时通讯也一样,是从Socket基础之后一点一点地做出来的。

  首先要学会理解和使用ServerSocket和Socket来进行流的输入与输出。

  wKioL1ZC_EySrIk5AABRu9-zvkY061.png 


  掌握TCP/IP协议,UDP协议,3次握手到底怎么回事(面试爱问)。即时通讯用的是XMPP协议,后面

  再研究。

  

  即时通讯的分类:

  wKiom1ZC-7ehr5ynAABs2E3JwMU214.png 

2.准备工作

  实体类与XML、JSON之间的相互转换


   

3.即时通讯类的模型构建与实体类实现 

 本文章以在线代理通讯来说明如何实现即时通讯,包括服务器端和客户端

 1.服务器端的简单搭建:

   创建一个ServerSocket,指定客户端连入的端口号,accept方法无限循环地监听客户端的状态

  (登录、注销等等),因为accept方法是阻塞的,所以无限循环不会出现卡死的问题。

   

public class QQImServer {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			// ① 创建一个线程 等其他客户端的连接
			final ServerSocket server = new ServerSocket(5222);
			System.out.println("---服务器启动---" + new Date().toString());
			new Thread() {//
				public void run() {
					while (true) {
						QQConnection conn = null;
						try {
							Socket client = server.accept();
							System.out.println("---有客户端接入---" + client);
							// ② 如果客户端连接成功分配置一个线程
							conn = new QQConnection(client);
							conn.addOnRecevieMsgListener(new LoginMsgListener(conn));
							conn.addOnRecevieMsgListener(new ChatP2PListener());
							conn.addOnRecevieMsgListener(new ChatRoomListener());
							conn.addOnRecevieMsgListener(new LoginOutListener());
							// ③ 该线程内等待用户数据
							conn.connect();
							// ④ 分配一个线程给客户端
						} catch (IOException e) {
							e.printStackTrace();
							conn.disconnect();
						}
					}
				};
			}.start();

		} catch (Exception e) {//
			e.printStackTrace();
		}
	}

}

  

 注意上面代码中,并非一个简简单单的ServerSocket,与平常所见的小demo不一样,就是对于Client

 客户端的处理逻辑显得稍微复杂了点。有几个核心类QQConnection(实则是一个线程,用来维护每一

 个客户端),几个客户端状态监听器LoginMsgListener(监听上线操作)、ChatP2PListener(监

 听点对点通讯)、ChatRoomListener(监听一个房间,也就是多个客户端的通讯)、

 LoginOutListener(监听下线)。


 上面4个监听类Listener的父类MessageSender封装了向一个或多个客户端发送消息的方法。

 QQConnectionManager用来管理连接进来的客户端,管理上线和下线(包括数据库操作)


 QQMessageType封装了客户端的多种状态

 下面这个是服务器端的结构: