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存储 推送需要的身份信息。以上属于个人口头话理解。

 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>
时间: 2024-10-10 23:22:25

javaweb webSocket 实现简单的点对点聊天功能的相关文章

[Nodejs]初探nodejs学习笔记- 如何使用nodejs搭建简单的UDP聊天功能

何为UDP(User Datagram Protocol)? 从baidu摘过来一段:UDP,用户数据报协议,与所熟知的TCP(传输控制协议)协议一样,UDP协议直接位于IP(网际协议)协议的顶层.根据OSI(开放系统互连)参考模型,UDP和TCP都属于传输层协议.UDP协议的主要作用是将网络数据流量压缩成数据包的形式.一个典型的数据包就是一个二进制数据的传输单位.每一个数据包的前8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据. UDP报文没有可靠性保证.顺序保证和流量控制字段等,可

WebSocket实现简单的在线聊天

SuperWebSocket在WebService中的应用 最开始使用是寄托在IIS中,发布之后测试时半个小时就会断开,所以改为WindowsService 1. 新建Windows服务项目[TestWindowsService],重命名Service1为MyWebSocketService 2. 打开MyWebSocketService设计视图,右键,添加安装程序,自动添加ProjectInstaller.cs. 打开设计视图,选中ServiceInstaller1,右键修改属性: Servi

WebSocket实现简单的web聊天室

1.需要Tomcat7.0所以服务器 2.需要JDK7.0 3.手工加入Tomcat7.0中lib目录下的一下三个包catalina.jar.tomcat-coyote.jar.websocket-api.jar 4.项目部署后,请将服务器中当前项目下的catalina.jar.tomcat-coyote.jar.websocket-api.jar三个包删除. 5.项目目录结构如下 Servlet代码 package com.yc.websockets; import java.io.IOExc

Unity3D 实现简单的语音聊天 [iOS版本]

现在很多手机游戏中的聊天系统都加入语音聊天的功能,相比于传统的文字聊天,语音聊天在MMORPG中显得尤为重要,毕竟直接口头交流总比你码字快得多了,也更直观些. 实现语音聊天的方法很多,U3D中有不少第三方的插件,提供了很多功能强大的语音功能,具体有哪些我就不一一举例了(其实我都没用过- -!),本文想从一个原生开发的角度去实现一个简单的语音聊天功能. 语音聊天大概流程如图: 上图中可以看到,客户端录制语音数据,并进行编码转换,数据压缩,然后把语音数据发送到语音服务器,语音服务器进行派发功能(语音

HTML5 WebSocket实现点对点聊天的示例代码

HTML5的websocket与Tomcat实现了多人聊天,那是最简单也是最基本的,其中注意的就是开发环境,要满足jdk1.7和tomcat8,当然了tom7的7.063也行,在网站上找到了用google关于websocket的点对点聊天,更好的是可以和大多数系统很好的配合起来看下效果图. 因为是模拟的,这里给出的是两个JSP页面A和B,里面分别向session里放了两个名字小明和小化,注意,这里的session是HttpSessionsession,之前多人聊天里的session是javax.

【WebSocket】---实现一对一聊天功能

实现一对一聊天功能 功能介绍:实现A和B单独聊天功能,即A发消息给B只能B接收,同样B向A发消息只能A接收. 本篇博客是在上一遍基础上搭建,上一篇博客地址:[WebSocket]---实现游戏公告功能.源码会在其它案例全部写完,在上传到gitHub,到时候会补源码地址. 先看演示效果: 一.案例解析 1.PTPContoller /** * 功能描述:简单版单人聊天 * 这里没有用到@SendTo("/topic/game_chat")来指定订阅地址,而是通过SimpMessaging

WebSocket 和 Golang 实现聊天功能

本文同步至 http://www.waylau.com/go-websocket-chat/ 这个示例应用程序展示了如何使用 WebSocket, Golang 和 jQuery 创建一个简单的web聊天应用程序.这个示例的源代码在 https://github.com/waylau/goChat . Running the example 运行示例 这个示例需要 Golang 开发环境. 该页面描述如何安装开发环境. 一旦你去启动和运行,您可以下载.构建和运行的例子, 使用命令: go get

基于html5 localStorage , web SQL, websocket的简单聊天程序

new function() { var ws = null; var connected = false; var serverUrl; var connectionStatus; var sendMessage; var connectButton; var disconnectButton; var sendButton; var open = function() { var url = serverUrl.val(); ws = new WebSocket(url); ws.onope

基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍。最后我们将会实现一个基于Server-Sent Event和Flask简单的在线聊天室。

基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍.最后我们将会实现一个基于Server-Sent Event和Flask简单的在线聊天室.