您的位置:首页 > 编程语言 > Java开发

javaweb webSocket 实现简单的点对点聊天功能

2015-07-19 14:55 866 查看
本文依据 http://redstarofsleep.iteye.com/blog/1488639?page=4  内容修改完成,实现点对点聊天

需要 jdk 7 , tomcat需要支持websocket的版本 

1.InitServlet

   该类主要是用来初始化构造将来存储用户身份信息的map仓库,利用其初始化方法Init 初始化仓库, 利用其静态方法getSocketList 获得对应的用户身份信息。

   webSocket ,我认为MessageInbound 用来识别登录人的信息,用它来找到对应的人,推送消息。每次登录都会产生一个MessageInbound。

  这里的 HashMap<String,MessageInbound>    :string 存储用户session的登录id,MessageInbound存储 推送需要的身份信息。以上属于个人口头话理解。

1 package socket;
2
3 import java.nio.CharBuffer;
4 import java.util.ArrayList;
5 import java.util.HashMap;
6 import java.util.List;
7
8 import javax.servlet.ServletConfig;
9 import javax.servlet.ServletException;
10 import javax.servlet.http.HttpServlet;
11
12 import org.apache.catalina.websocket.MessageInbound;
13
14 public class InitServlet extends HttpServlet {
15
16     private static final long serialVersionUID = -3163557381361759907L;
17
18     //private static List<MessageInbound> socketList;
19     private static HashMap<String,MessageInbound> socketList;
20
21     public void init(ServletConfig config) throws ServletException {
22 //        InitServlet.socketList = new ArrayList<MessageInbound>();
23         InitServlet.socketList = new HashMap<String,MessageInbound>();
24         super.init(config);
25         System.out.println("Server start============");
26     }
27
28     public static HashMap<String,MessageInbound> getSocketList() {
29         return InitServlet.socketList;
30     }
31 /*    public static List<MessageInbound> getSocketList() {
32         return InitServlet.socketList;
33     }
34 */}


 

2.MyWebSocketServlet 

  websocket用来建立连接的servlet,建立连接时,首先在session获取该登录人的userId,在调用MyMessageInbound构造函数传入userId

1 package socket;
2
3 import java.io.IOException;
4 import java.io.PrintWriter;
5 import java.nio.CharBuffer;
6
7 import javax.servlet.ServletException;
8 import javax.servlet.http.HttpServlet;
9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11
12 import org.apache.catalina.websocket.StreamInbound;
13 import org.apache.catalina.websocket.WebSocketServlet;
14 /**
15  *
16  * @ClassName: MyWebSocketServlet
17  * @Description: 建立连接时创立
18  * @author mangues
19  * @date 2015-7-19
20  */
21 public class MyWebSocketServlet extends WebSocketServlet {
22
23     public String getUser(HttpServletRequest request){
24         String userName = (String) request.getSession().getAttribute("user");
25         if(userName==null){
26             return null;
27         }
28         return userName;
29        // return (String) request.getAttribute("user");
30     }
31     @Override
32     protected StreamInbound 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 package socket;
2
3 import java.io.IOException;
4 import java.nio.ByteBuffer;
5 import java.nio.CharBuffer;
6 import java.util.HashMap;
7
8 import org.apache.catalina.websocket.MessageInbound;
9 import org.apache.catalina.websocket.WsOutbound;
10
11 import util.MessageUtil;
12
13 public class MyMessageInbound extends MessageInbound {
14
15     private String name;
16     public MyMessageInbound() {
17         super();
18     }
19
20     public MyMessageInbound(String name) {
21         super();
22         this.name = name;
23     }
24
25     @Override
26     protected void onBinaryMessage(ByteBuffer arg0) throws IOException {
27         // TODO Auto-generated method stub
28
29     }
30
31     @Override
32     protected void onTextMessage(CharBuffer msg) throws IOException {
33         //用户所发消息处理后的map
34         HashMap<String,String> messageMap = MessageUtil.getMessage(msg);    //处理消息类
35         //上线用户集合类map
36         HashMap<String, MessageInbound> userMsgMap = InitServlet.getSocketList();
37
38         String fromName = messageMap.get("fromName");    //消息来自人 的userId
39
40
41         String toName = messageMap.get("toName");         //消息发往人的 userId
42         //获取该用户
43         MessageInbound messageInbound = userMsgMap.get(toName);    //在仓库中取出发往人的MessageInbound
44
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     @Override
72     protected void onClose(int status) {
73         InitServlet.getSocketList().remove(this);
74         super.onClose(status);
75     }
76
77     @Override
78     protected void onOpen(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 package util;
2
3 import java.nio.CharBuffer;
4 import java.util.HashMap;
5 /**
6  *
7  * @ClassName: MessageUtil
8  * @Description: 消息处理类
9  * @author mangues
10  * @date 2015-7-19
11  */
12 public class MessageUtil {
13
14     public static HashMap<String,String> getMessage(CharBuffer msg) {
15         HashMap<String,String> map = new HashMap<String,String>();
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         return map;
22     }
23 }


 

5.web配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> 
<servlet>
<servlet-name>mywebsocket</servlet-name>
<servlet-class>socket.MyWebSocketServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mywebsocket</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

<servlet>
<servlet-name>initServlet</servlet-name>
<servlet-class>socket.InitServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>


 

 

6,。前端,为方便起见,我直接用了两个jsp,在其中用<%session.setAttribute("user","小明")%>;来表示登录。

      两个jsp没任何本质差别,只是用来表示两个不同的人登录,可以同两个浏览器打开不同的jsp,来聊天操作

   A.小化

1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2     pageEncoding="UTF-8"%>
3 <!DOCTYPE html>
4 <html>
5 <head>
6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
7 <title>Index</title>
8 <script type="text/javascript" src="js/jquery 2.1.1.min.js"></script>
9 <%session.setAttribute("user", "小化");%>
10 <script type="text/javascript">
11 var ws = null;
12 function startWebSocket() {
13     if ('WebSocket' in window)
14         ws = new WebSocket("ws://localhost:8080/webSocket/mywebsocket.do");
15     else if ('MozWebSocket' in window)
16         ws = new MozWebSocket("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 function sendMsg() {
40     var fromName = "小化";
41     var toName = document.getElementById('name').value;  //发给谁
42     var content = document.getElementById('writeMsg').value; //发送内容
43     ws.send(fromName+","+toName+","+content);
44 }
45 </script>
46 </head>
47 <body onload="startWebSocket();">
48 <p>聊天功能实现</p>
49 登录状态:
50 <span id="denglu" style="color:red;">正在登录</span>
51 <br>
52 登录人:
53 <span id="userName"></span>
54 <br>
55 <br>
56 <br>
57
58 发送给谁:<input type="text" id="name" value="小明"></input>
59 <br>
60 发送内容:<input type="text" id="writeMsg"></input>
61 <br>
62 聊天框:<textarea rows="13" cols="100" readonly id="xiaoxi"></textarea>
63 <br>
64 <input type="button" value="send" onclick="sendMsg()"></input>
65 </body>
66 </html>


 B.小明

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Index</title>
<script type="text/javascript" src="js/jquery 2.1.1.min.js"></script>
<%session.setAttribute("user", "小明");%>
<script type="text/javascript">
var ws = null;
function startWebSocket() {
if ('WebSocket' in window)
ws = new WebSocket("ws://localhost:8080/webSocket/mywebsocket.do");
else if ('MozWebSocket' in window)
ws = new MozWebSocket("ws://localhost:8080/webSocket/mywebsocket.do");
else
alert("not support");

ws.onmessage = function(evt) {
console.log(evt);
//alert(evt.data);
$("#xiaoxi").val(evt.data);
};

ws.onclose = function(evt) {
//alert("close");
document.getElementById('denglu').innerHTML="离线";
};

ws.onopen = function(evt) {
//alert("open");
document.getElementById('denglu').innerHTML="在线";
document.getElementById('userName').innerHTML="小明";
};
}

function sendMsg() {
var fromName = "小明";
var toName = document.getElementById('name').value;  //发给谁
var content = document.getElementById('writeMsg').value; //发送内容
ws.send(fromName+","+toName+","+content);
}
</script>
</head>
<body onload="startWebSocket();">
<p>聊天功能实现</p>
登录状态:
<span id="denglu" style="color:red;">正在登录</span>
<br>
登录人:
<span id="userName"></span>
<br>
<br>
<br>

发送给谁:<input type="text" id="name" value="小化"></input>
<br>
发送内容:<input type="text" id="writeMsg"></input>
<br>
聊天框:<textarea rows="13" cols="100" readonly id="xiaoxi"></textarea>
<br>
<input type="button" value="send" onclick="sendMsg()"></input>
</body>
</html>


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息