基于webSocket的多人聊天系统

JSR356实现WebSocket(该方式的代码需要部署在Tomcat7.0.47以上的版本才能运行)
WebSocketTest:
[java]  view plain  copy
  1. package com.solin.chat;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.ArrayList;  
  5. import java.util.List;  
  6.   
  7. import javax.websocket.OnClose;  
  8. import javax.websocket.OnError;  
  9. import javax.websocket.OnMessage;  
  10. import javax.websocket.OnOpen;  
  11. import javax.websocket.Session;  
  12. import javax.websocket.server.ServerEndpoint;  
  13.   
  14. /** 
  15.  * JSR356实现WebSocket有两种方式,一种是使用注解的,另一种是继承javax.websocket.Endpoint类, 
  16.  * 推荐方式是使用注解(本例使用注解) 
  17.  *  
  18.  * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端, 
  19.  * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端 
  20.  */  
  21. @ServerEndpoint("/websocket")  
  22. public class WebSocketTest {  
  23.     //连接池,用来保存每个客户端连接的对象  
  24.     private static List<WebSocketTest> msgList   
  25.         = new ArrayList<WebSocketTest>();  
  26.       
  27.     //与某个客户端的连接会话,需要通过它来给客户端发送数据  
  28.     private Session session;  
  29.       
  30.     /** 
  31.      * 连接建立成功调用的方法 
  32.      * @param session  可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据 
  33.      */  
  34.     @OnOpen  
  35.     public void onOpen(Session session){  
  36.         this.session = session;  
  37.         msgList.add(this);  
  38.         System.out.println("有新连接加入");  
  39.     }  
  40.       
  41.     /** 
  42.      * 连接关闭调用的方法 
  43.      */  
  44.     @OnClose  
  45.     public void onClose(){  
  46.         msgList.remove(this);  
  47.         System.out.println("有连接关闭");  
  48.     }  
  49.       
  50.     /** 
  51.      * 收到客户端消息后调用的方法 
  52.      * @param message 客户端发送过来的消息 
  53.      * @param session 可选的参数 
  54.      */  
  55.     @OnMessage  
  56.     public void onMessage(String message, Session session) {  
  57.         System.out.println("来自客户端的消息:" + message);  
  58.         //群发消息  
  59.         for(WebSocketTest item: msgList){  
  60.             try {  
  61.                 item.sendMessage(message);  
  62.             } catch (IOException e) {  
  63.                 e.printStackTrace();  
  64.                 continue;  
  65.             }  
  66.         }  
  67.     }  
  68.       
  69.     /** 
  70.      * 发生错误时调用 
  71.      * @param session 
  72.      * @param error 
  73.      */  
  74.     @OnError  
  75.     public void onError(Session session, Throwable error){  
  76.         System.out.println("发生错误");  
  77.         error.printStackTrace();  
  78.     }  
  79.       
  80.     /** 
  81.      * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。 
  82.      * @param message 
  83.      * @throws IOException 
  84.      */  
  85.     public void sendMessage(String message) throws IOException{  
  86.         this.session.getBasicRemote().sendText(message);//发送消息给客户端  
  87.         //this.session.getAsyncRemote().sendText(message);  
  88.     }  
  89. }  

WebSocket客户端

index.jsp
[html]  view plain  copy
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  4. <html>  
  5.     <head>  
  6.         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  7.         <title>基于Java服务器端的消息主动推送技术揭秘</title>  
  8.         <style type="text/css">  
  9.             *{  
  10.                 margin:0;  
  11.                 padding:0;  
  12.             }  
  13.             body{background:#e2e2e2;}  
  14.             .chatBox{  
  15.                 width:680px;  
  16.                 margin:0 auto;  
  17.                 text-align:center;  
  18.             }  
  19.             .chatBox h1{  
  20.                 font-size:30px;  
  21.                 color:#D29575;  
  22.                 margin-top:20px;  
  23.             }  
  24.             .tipBox{  
  25.                 text-align:left;  
  26.                 line-height:35px;  
  27.             }  
  28.             .inputText{height:30px;}  
  29.             .chatContainer{  
  30.                 width:100%;  
  31.                 height:300px;  
  32.                 overflow:hidden;  
  33.                 text-align:left;  
  34.                 border:1px solid #000;  
  35.             }  
  36.             .sendBox{text-align:left;}  
  37.             button{  
  38.                 height:30px;  
  39.                 width:80px;  
  40.                 color:#fff;  
  41.                 font-size:20px;  
  42.                 background:#2996A1;  
  43.                 margin:7px auto;  
  44.                 cursor:pointer;  
  45.                 outline:none;  
  46.             }  
  47.         </style>  
  48.         <script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>  
  49.         <script type="text/javascript">  
  50.             var ws;  
  51.             var socketCreated = false;  
  52.             var isLogout = false;  
  53.             //页面一加载就执行  
  54.             $(function(){  
  55.                 $("#sendBox").hide();  
  56.                 //判断浏览器是否支持WebSocket  
  57.                 if(window.WebSocket || window.MozWebSocket){  
  58.                     $("#chatContainer").append("<span style='color:green;'>您的浏览器支持WebSocket,您可以尝试连接到聊天服务器!</span><br/>");  
  59.                     $("#conUrl").val("localhost:8080/Solin_Chat/webChat");  
  60.                 }else{  
  61.                     $("#chatContainer").append("<span style='color:red;'>浏览器不支持WebSocket,请更换浏览器!</span><br/>");  
  62.                 }  
  63.                 //绑定消息发送事件  
  64.                 $("#sendMsgBtn").click(function(){  
  65.                     var msg = $("#msgContent").val().trim();  
  66.                     if(msg != ""){  
  67.                         ws.send($("#loginUser").val()+"说:"+msg+"<br/>");  
  68.                     }  
  69.                     $("#msgContent").val("");  
  70.                 });  
  71.                   
  72.                 //给连接按钮绑定点击事件  
  73.                 $("#conBtn").click(function(){  
  74.                     //0:正在连接   1:已连接   2:正在关闭连接   3:已关闭连接  
  75.                     if(socketCreated && (ws.readyState == 0 || ws.readyState == 1)){//已经连接了  
  76.                         ws.send("<span style='color:blue;font-weight:bold'>["+$("#loginUser").val()+"]离开了聊天室...</span><br/>")  
  77.                         socketCreated = false;  
  78.                         isLogout = true;  
  79.                         ws.close();//关闭连接  
  80.                         $("#conBtn").html("连接");//修改按钮文字  
  81.                         $("#sendBox").hide();  
  82.                     }else{//还没连接  
  83.                         //申请WebSocket对象  
  84.                         if("WebSocket" in window){  
  85.                             ws = new WebSocket("ws://"+$("#conUrl").val());  
  86.                         }else if("MozWebSocket" in window){  
  87.                             ws = new MozWebSocket("ws://"+$("#conUrl").val());  
  88.                         }  
  89.                         socketCreated = true;  
  90.                         isLogout = false;  
  91.                         $("#conBtn").html("断开");//修改按钮文字  
  92.                           
  93.                         //注册事件  
  94.                         ws.onopen = wsOnOpen;//获得连接时  
  95.                         ws.onmessage = wsOnMessage;//接收消息时  
  96.                         ws.onclose = wsOnClose;//关闭连接时  
  97.                         ws.onerror = wsOnError;//处理发生错误时(消息发送错误、连接错误)  
  98.                     }  
  99.                 });  
  100.             });  
  101.               
  102.             function wsOnOpen(){  
  103.                 ws.send("<span style='color:red;font-weight:bold'>["+$("#loginUser").val()+"]进入了聊天室...</span><br/>");  
  104.                 $("#sendBox").show();  
  105.             }  
  106.               
  107.             function wsOnMessage(event){  
  108.                 $("#chatContainer").append(event.data);  
  109.             }  
  110.               
  111.             function wsOnClose(){  
  112.                   
  113.             }  
  114.               
  115.             function wsOnError(){  
  116.                 $("#chatContainer").append("连接错误,请检查...<br/>");  
  117.             }  
  118.         </script>  
  119.     </head>  
  120.     <body>  
  121.         <div class="chatBox">  
  122.             <h1>基于Java服务器端的消息主动推送技术揭秘</h1>  
  123.             <div class="tipBox">  
  124.                 服务器地址:<input type="text" class="inputText" id="conUrl" style="width:315px;" />  
  125.                 用户名:<input type="text" class="inputText" id="loginUser" value="Solin" style="width:190px;" />  
  126.                 <button type="button" id="conBtn">连接</button>  
  127.             </div>  
  128.             <div class="chatContainer" id="chatContainer"></div>  
  129.             <div class="sendBox" id="sendBox">  
  130.                 <input type="text" class="inputText" style="width:588px;" id="msgContent" />  
  131.                 <button type="button" id="sendMsgBtn">发送</button>  
  132.             </div>  
  133.         </div>  
  134.     </body>  
  135. </html>  

测试结果


1、什么是WebSocket? 
WebSocket 是一种自然的全双工、双向、单套接字连接。使用WebSocket,你的HTTP 请求变成打开WebSocket 连接(WebSocket 或者WebSocket over TLS(TransportLayer Security,传输层安全性,原称“SSL”))的单一请求,并且重用从客户端到服务器以及服务器到客户端的同一连接。WebSocket 减少了延迟,因为一旦建立起WebSocket 连接,服务器可以在消息可用时发送它们。例如,和轮询不同,WebSocket只发出一个请求。服务器不需要等待来自客户端的请求。相似地,客户端可以在任何时候向服务器发送消息。相比轮询不管是否有可用消息,每隔一段时间都发送一个请求,单一请求大大减少了延迟。 
2、WebSocket API 
WebSocket API 使你可以通过Web,在客户端应用程序和服务器端进程之间建立全双工的双向通信。WebSocket 接口规定了可用于客户端的方法以及客户端与网络的交互方式。 
3、WebSocket构造函数 
为了建立到服务器的WebSocket连接,使用WebSocket接口,通过指向一个代表所要连接端点的URL,实例化一个WebSocket对象。WebSocket 协议定义了两种URL方案(URL scheme)—ws和wss,分别用于客户端和服务器之间的非加密与加密流量。 
实例:var ws = new WebSocket("ws://www.websocket.org"); 
4、WebSocket事件 
WebSocket API 是纯事件驱动的。应用程序代码监听WebSocket对象上的事件,以便处理输入数据和连接状态的改变。WebSocket协议也是事件驱动的。 
WebSocket对象调度4个不同的事件: 
A、open事件: 
一旦服务器响应了WebSocket连接请求,open事件触发并建立一个连接。open事件对应的回调函数称作onopen 
实例:

ws.onopen = function(e) {
    console.log("Connection open...");
};
  • 1
  • 2
  • 3

B、messagess事件: 
message事件在接收到消息时触发,对应于该事件的回调函数是onmessage。 
实例:

ws.onmessage = function(e) {
    if(typeof e.data === "string"){
        console.log("String message received", e, e.data);
    } else {
        console.log("Other message received", e, e.data);
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

C、error事件: 
error 事件在响应意外故障的时候触发。与该事件对应的回调函数为onerror。 
实例:

ws.onerror = function(e){
    console.log('websocked error');
    handerError();
}
  • 1
  • 2
  • 3
  • 4

D、close事件: 
close 事件在WebSocket 连接关闭时触发。对应于close 事件的回调函数是onclose。 
实例:

ws.onclose = function(e) {
    console.log("Connection closed", e);
};
  • 1
  • 2
  • 3

5、WebSocket方法 
WebSocket 对象有两个方法:send() 和close()。 
A、 send() 方法: 
使用WebSocket在客户端和服务器之间建立全双工双向连接后,就可以在连接打开时调用send() 方法。使用send() 方法可以从客户端向服务器发送消息。在发送一条或者多条消息之后,可以保持连接打开,或者调用close() 方法终止连接。 
实例:

ws.send("Hello WebSocket!");
  • 1

B、close ()方法: 
使用close()方法,可以关闭WebSocket连接或者终止连接尝试。如果连接已经关闭,该方法就什么都不做。在调用close()之后,不能在已经关闭的WebSocket上发送任何数据。可以向close()方法传递两个可选参数:code(数字型的状态代码)和reason(一个文本字符串)。传递这些参数能够向服务器传递关于客户关闭连接原因的信息。 
注:以上是对 WebSocket的简单介绍,下面将用一个简单的网页实时聊天案例来介绍如何使用WebSocket


原文地址:链接链接2

猜你喜欢

转载自blog.csdn.net/qq_37819347/article/details/80016848