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

来源:互联网 发布:ai cs6是什么软件 编辑:程序博客网 时间:2024/05/01 21:42

本文依据 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 mangues19  * @date 2015-7-1920  */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     @Override32     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         //用户所发消息处理后的map34         HashMap<String,String> messageMap = MessageUtil.getMessage(msg);    //处理消息类35         //上线用户集合类map36         HashMap<String, MessageInbound> 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     @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 mangues10  * @date 2015-7-1911  */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     else18         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>
复制代码

 


0 0