天天看點

javaweb webSocket 實作簡單的點對點聊天功能

本文依據 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存儲 推送需要的身份資訊。以上屬于個人口頭話了解。

javaweb webSocket 實作簡單的點對點聊天功能
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 */}      
javaweb webSocket 實作簡單的點對點聊天功能

2.MyWebSocketServlet 

  websocket用來建立連接配接的servlet,建立連接配接時,首先在session擷取該登入人的userId,在調用MyMessageInbound構造函數傳入userId

javaweb webSocket 實作簡單的點對點聊天功能
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 }      
javaweb webSocket 實作簡單的點對點聊天功能

3.onOpen方法調用InitServlet的map身份倉庫,

放入使用者userId 和 對應該登入使用者的websocket身份資訊MessageInbound (可以用userId來尋找到推送需要的 身份MessageInbound )

onTextMessage :用來擷取消息,并發送消息

      
javaweb webSocket 實作簡單的點對點聊天功能
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 }      
javaweb webSocket 實作簡單的點對點聊天功能

4.消息處理類,處理前端發來的消息

javaweb webSocket 實作簡單的點對點聊天功能
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 }      
javaweb webSocket 實作簡單的點對點聊天功能

5.web配置

javaweb webSocket 實作簡單的點對點聊天功能
<?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>      
javaweb webSocket 實作簡單的點對點聊天功能

6,。前端,為友善起見,我直接用了兩個jsp,在其中用<%session.setAttribute("user","小明")%>;來表示登入。

      兩個jsp沒任何本質差别,隻是用來表示兩個不同的人登入,可以同兩個浏覽器打開不同的jsp,來聊天操作

   A.小化

javaweb webSocket 實作簡單的點對點聊天功能
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>      
javaweb webSocket 實作簡單的點對點聊天功能

 B.小明

javaweb webSocket 實作簡單的點對點聊天功能
<%@ 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>      
javaweb webSocket 實作簡單的點對點聊天功能

繼續閱讀