需要 jdk 7 , tomcat需要支持websocket的版本
1.InitServlet
该类主要是用来初始化构造将来存储用户身份信息的map仓库,利用其初始化方法Init 初始化仓库, 利用其静态方法getSocketList 获得对应的用户身份信息。
webSocket ,我认为MessageInbound 用来识别登录人的信息,用它来找到对应的人,推送消息。每次登录都会产生一个MessageInbound。
这里的 HashMap :string 存储用户session的登录id,MessageInbound存储 推送需要的身份信息。以上属于个人口头话理解。
1 packagesocket;2
3 importjava.nio.CharBuffer;4 importjava.util.ArrayList;5 importjava.util.HashMap;6 importjava.util.List;7
8 importjavax.servlet.ServletConfig;9 importjavax.servlet.ServletException;10 importjavax.servlet.http.HttpServlet;11
12 importorg.apache.catalina.websocket.MessageInbound;13
14 public class InitServlet extendsHttpServlet {15
16 private static final long serialVersionUID = -3163557381361759907L;17
18 //private static List socketList;
19 private static HashMapsocketList;20
21 public void init(ServletConfig config) throwsServletException {22 //InitServlet.socketList = new ArrayList();
23 InitServlet.socketList = new HashMap();24 super.init(config);25 System.out.println("Server start============");26 }27
28 public static HashMapgetSocketList() {29 returnInitServlet.socketList;30 }31 /*public static List getSocketList() {32 return InitServlet.socketList;33 }34 */}
2.MyWebSocketServlet
websocket用来建立连接的servlet,建立连接时,首先在session获取该登录人的userId,在调用MyMessageInbound构造函数传入userId
1 packagesocket;2
3 importjava.io.IOException;4 importjava.io.PrintWriter;5 importjava.nio.CharBuffer;6
7 importjavax.servlet.ServletException;8 importjavax.servlet.http.HttpServlet;9 importjavax.servlet.http.HttpServletRequest;10 importjavax.servlet.http.HttpServletResponse;11
12 importorg.apache.catalina.websocket.StreamInbound;13 importorg.apache.catalina.websocket.WebSocketServlet;14 /**
15 *16 * @ClassName: MyWebSocketServlet17 * @Description: 建立连接时创立18 *@authormangues19 * @date 2015-7-1920 */
21 public class MyWebSocketServlet extendsWebSocketServlet {22
23 publicString getUser(HttpServletRequest request){24 String userName = (String) request.getSession().getAttribute("user");25 if(userName==null){26 return null;27 }28 returnuserName;29 //return (String) request.getAttribute("user");
30 }31 @Override32 protectedStreamInbound createWebSocketInbound(String arg0,33 HttpServletRequest request) {34 System.out.println("##########");35 return new MyMessageInbound(this.getUser(request));36 }37
38 }
3.onOpen方法调用InitServlet的map身份仓库,
放入用户userId 和 对应该登录用户的websocket身份信息MessageInbound (可以用userId来寻找到推送需要的 身份MessageInbound )
onTextMessage :用来获取消息,并发送消息
1 packagesocket;2
3 importjava.io.IOException;4 importjava.nio.ByteBuffer;5 importjava.nio.CharBuffer;6 importjava.util.HashMap;7
8 importorg.apache.catalina.websocket.MessageInbound;9 importorg.apache.catalina.websocket.WsOutbound;10
11 importutil.MessageUtil;12
13 public class MyMessageInbound extendsMessageInbound {14
15 privateString name;16 publicMyMessageInbound() {17 super();18 }19
20 publicMyMessageInbound(String name) {21 super();22 this.name =name;23 }24
25 @Override26 protected void onBinaryMessage(ByteBuffer arg0) throwsIOException {27 //TODO Auto-generated method stub
28
29 }30
31 @Override32 protected void onTextMessage(CharBuffer msg) throwsIOException {33 //用户所发消息处理后的map
34 HashMap messageMap =MessageUtil.getMessage(msg); //处理消息类35 //上线用户集合类map
36 HashMap userMsgMap =InitServlet.getSocketList();37
38 String fromName = messageMap.get("fromName"); //消息来自人 的userId39
40
41 String toName = messageMap.get("toName"); //消息发往人的 userId42 //获取该用户
43 MessageInbound messageInbound =userMsgMap.get(toName); //在仓库中取出发往人的MessageInbound44
45
46
47 if(messageInbound!=null){ //如果发往人 存在进行操作48 WsOutbound outbound =messageInbound.getWsOutbound();49
50
51 String content = messageMap.get("content"); //获取消息内容
52 String msgContentString = fromName + " " +content; //构造发送的消息53
54 //发出去内容
55 CharBuffer toMsg =CharBuffer.wrap(msgContentString.toCharArray());56 outbound.writeTextMessage(toMsg); //57 outbound.flush();58 }59
60
61
62 /*for (MessageInbound messageInbound : InitServlet.getSocketList()) {63 CharBuffer buffer = CharBuffer.wrap(msg);64 WsOutbound outbound = messageInbound.getWsOutbound();65 outbound.writeTextMessage(buffer);66 outbound.flush();67 }*/
68
69 }70
71 @Override72 protected void onClose(intstatus) {73 InitServlet.getSocketList().remove(this);74 super.onClose(status);75 }76
77 @Override78 protected voidonOpen(WsOutbound outbound) {79 super.onOpen(outbound);80 //登录的用户注册进去
81 if(name!=null){82 InitServlet.getSocketList().put(name, this);83 }84 //InitServlet.getSocketList().add(this);
85 }86
87
88 }
4.消息处理类,处理前端发来的消息
1 packageutil;2
3 importjava.nio.CharBuffer;4 importjava.util.HashMap;5 /**
6 *7 * @ClassName: MessageUtil8 * @Description: 消息处理类9 *@authormangues10 * @date 2015-7-1911 */
12 public classMessageUtil {13
14 public static HashMapgetMessage(CharBuffer msg) {15 HashMap map = new HashMap();16 String msgString =msg.toString();17 String m[] = msgString.split(",");18 map.put("fromName", m[0]);19 map.put("toName", m[1]);20 map.put("content", m[2]);21 returnmap;22 }23 }
5.web配置
mywebsocket
socket.MyWebSocketServlet
mywebsocket
*.do
initServlet
socket.InitServlet
1
index.jsp
6,。前端,为方便起见,我直接用了两个jsp,在其中用;来表示登录。
两个jsp没任何本质差别,只是用来表示两个不同的人登录,可以同两个浏览器打开不同的jsp,来聊天操作
A.小化
1
2 pageEncoding="UTF-8"%>
3
4
5
6
7
Index8
9
10
11 varws= null;12 functionstartWebSocket() {13 if('WebSocket' inwindow)14 ws= newWebSocket("ws://localhost:8080/webSocket/mywebsocket.do");15 else if('MozWebSocket' inwindow)16 ws= newMozWebSocket("ws://localhost:8080/webSocket/mywebsocket.do");17 else
18 alert("not support");19
20
21 ws.onmessage= function(evt) {22 //alert(evt.data);
23 console.log(evt);24 $("#xiaoxi").val(evt.data);25 };26
27 ws.onclose= function(evt) {28 //alert("close");
29 document.getElementById('denglu').innerHTML="离线";30 };31
32 ws.onopen= function(evt) {33 //alert("open");
34 document.getElementById('denglu').innerHTML="在线";35 document.getElementById('userName').innerHTML='小化';36 };37 }38
39 functionsendMsg() {40 varfromName= "小化";41 vartoName=document.getElementById('name').value;//发给谁
42 varcontent=document.getElementById('writeMsg').value;//发送内容
43 ws.send(fromName+","+toName+","+content);44 }45
46
47
48
聊天功能实现
49 登录状态:50 正在登录
51
52 登录人:53
54
55
56
57
58 发送给谁:
59
60 发送内容:
61
62 聊天框:
63
64
65
66