java WebSocket 简易聊天消息推送

环境:

JDK.1.7.0_51

apache-tomcat-7.0.53

Java jar包:tomcat-coyote.jar、tomcat-juli.jar、websocket-api.jar

ChatAnnotation消息发送类:

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. import java.io.IOException;  
  2. import java.util.HashMap;  
  3. import java.util.Map;  
  4. import java.util.concurrent.atomic.AtomicInteger;  
  5.   
  6. import javax.websocket.OnClose;  
  7. import javax.websocket.OnError;  
  8. import javax.websocket.OnMessage;  
  9. import javax.websocket.OnOpen;  
  10. import javax.websocket.Session;  
  11. import javax.websocket.server.ServerEndpoint;  
  12.   
  13. import org.apache.juli.logging.Log;  
  14. import org.apache.juli.logging.LogFactory;  
  15.   
  16. import com.util.HTMLFilter;   
  17.   
  18. /** 
  19.  * WebSocket 消息推送服务类 
  20.  * @author 胡汉三 
  21.  * 
  22.  * 2014-11-18 下午7:53:13 
  23.  */  
  24. @ServerEndpoint(value = "/websocket/chat")  
  25. public class ChatAnnotation {  
  26.   
  27.     private static final Log log = LogFactory.getLog(ChatAnnotation.class);  
  28.   
  29.     private static final String GUEST_PREFIX = "Guest";  
  30.     private static final AtomicInteger connectionIds = new AtomicInteger(0);  
  31.     private static final Map<String,Object> connections = new HashMap<String,Object>();  
  32.   
  33.     private final String nickname;  
  34.     private Session session;  
  35.   
  36.     public ChatAnnotation() {  
  37.         nickname = GUEST_PREFIX + connectionIds.getAndIncrement();  
  38.     }  
  39.   
  40.   
  41.     @OnOpen  
  42.     public void start(Session session) {  
  43.         this.session = session;  
  44.         connections.put(nickname, this);   
  45.         String message = String.format("* %s %s", nickname, "has joined.");  
  46.         broadcast(message);  
  47.     }  
  48.   
  49.   
  50.     @OnClose  
  51.     public void end() {  
  52.         connections.remove(this);  
  53.         String message = String.format("* %s %s",  
  54.                 nickname, "has disconnected.");  
  55.         broadcast(message);  
  56.     }  
  57.   
  58.   
  59.     /** 
  60.      * 消息发送触发方法 
  61.      * @param message 
  62.      */  
  63.     @OnMessage  
  64.     public void incoming(String message) {  
  65.         // Never trust the client  
  66.         String filteredMessage = String.format("%s: %s",  
  67.                 nickname, HTMLFilter.filter(message.toString()));  
  68.         broadcast(filteredMessage);  
  69.     }  
  70.   
  71.     @OnError  
  72.     public void onError(Throwable t) throws Throwable {  
  73.         log.error("Chat Error: " + t.toString(), t);  
  74.     }  
  75.   
  76.     /** 
  77.      * 消息发送方法 
  78.      * @param msg 
  79.      */  
  80.     private static void broadcast(String msg) {  
  81.         if(msg.indexOf("Guest0")!=-1){  
  82.             sendUser(msg);  
  83.         } else{  
  84.             sendAll(msg);  
  85.         }  
  86.     }   
  87.       
  88.     /** 
  89.      * 向所有用户发送 
  90.      * @param msg 
  91.      */  
  92.     public static void sendAll(String msg){  
  93.         for (String key : connections.keySet()) {  
  94.             ChatAnnotation client = null ;  
  95.             try {  
  96.                 client = (ChatAnnotation) connections.get(key);  
  97.                 synchronized (client) {  
  98.                     client.session.getBasicRemote().sendText(msg);  
  99.                 }  
  100.             } catch (IOException e) {   
  101.                 log.debug("Chat Error: Failed to send message to client", e);  
  102.                 connections.remove(client);  
  103.                 try {  
  104.                     client.session.close();  
  105.                 } catch (IOException e1) {  
  106.                     // Ignore  
  107.                 }  
  108.                 String message = String.format("* %s %s",  
  109.                         client.nickname, "has been disconnected.");  
  110.                 broadcast(message);  
  111.             }  
  112.         }  
  113.     }  
  114.       
  115.     /** 
  116.      * 向指定用户发送消息  
  117.      * @param msg 
  118.      */  
  119.     public static void sendUser(String msg){  
  120.         ChatAnnotation c = (ChatAnnotation)connections.get("Guest0");  
  121.         try {  
  122.             c.session.getBasicRemote().sendText(msg);  
  123.         } catch (IOException e) {  
  124.             log.debug("Chat Error: Failed to send message to client", e);  
  125.             connections.remove(c);  
  126.             try {  
  127.                 c.session.close();  
  128.             } catch (IOException e1) {  
  129.                 // Ignore  
  130.             }  
  131.             String message = String.format("* %s %s",  
  132.                     c.nickname, "has been disconnected.");  
  133.             broadcast(message);    
  134.         }   
  135.     }  
  136. }  

HTMLFilter工具类:

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * HTML 工具类  
  3.  * 
  4.  * @author 胡汉三 
  5.  */  
  6. public final class HTMLFilter {  
  7.     public static String filter(String message) {  
  8.         if (message == null)  
  9.             return (null);  
  10.         char content[] = new char[message.length()];  
  11.         message.getChars(0, message.length(), content, 0);  
  12.         StringBuilder result = new StringBuilder(content.length + 50);  
  13.         for (int i = 0; i < content.length; i++) {  
  14.             switch (content[i]) {  
  15.             case '<':  
  16.                 result.append("<");  
  17.                 break;  
  18.             case '>':  
  19.                 result.append(">");  
  20.                 break;  
  21.             case '&':  
  22.                 result.append("&");  
  23.                 break;  
  24.             case '"':  
  25.                 result.append(""");  
  26.                 break;  
  27.             default:  
  28.                 result.append(content[i]);  
  29.             }  
  30.         }  
  31.         return (result.toString());  
  32.     }  
  33. }  

页面:

[html]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6.   
  7. <?xml version="1.0" encoding="UTF-8"?>  
  8. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">  
  9. <head>  
  10.     <title>测试</title>  
  11.     <style type="text/css">  
  12.         input#chat {  
  13.             width: 410px  
  14.         }  
  15.   
  16.         #console-container {  
  17.             width: 400px;  
  18.         }  
  19.   
  20.         #console {  
  21.             border: 1px solid #CCCCCC;  
  22.             border-right-color: #999999;  
  23.             border-bottom-color: #999999;  
  24.             height: 170px;  
  25.             overflow-y: scroll;  
  26.             padding: 5px;  
  27.             width: 100%;  
  28.         }  
  29.   
  30.         #console p {  
  31.             padding: 0;  
  32.             margin: 0;  
  33.         }  
  34.  </style>  
  35.     <script type="text/javascript">  
  36.   
  37.         var Chat = {};  
  38.   
  39.         Chat.socket = null;  
  40.   
  41.         Chat.connect = (function(host) {  
  42.             if ('WebSocket' in window) {  
  43.                 Chat.socket = new WebSocket(host);  
  44.             } else if ('MozWebSocket' in window) {  
  45.                 Chat.socket = new MozWebSocket(host);  
  46.             } else {  
  47.                 Console.log('Error: WebSocket is not supported by this browser.');  
  48.                 return;  
  49.             }  
  50.   
  51.             Chat.socket.onopen = function () {  
  52.                 Console.log('Info: WebSocket connection opened.');  
  53.                 document.getElementById('chat').onkeydown = function(event) {  
  54.                     if (event.keyCode == 13) {  
  55.                         Chat.sendMessage();  
  56.                     }  
  57.                 };  
  58.             };  
  59.   
  60.             Chat.socket.onclose = function () {  
  61.                 document.getElementById('chat').onkeydown = null;  
  62.                 Console.log('Info: WebSocket closed.');  
  63.             };  
  64.   
  65.             Chat.socket.onmessage = function (message) {  
  66.                 Console.log(message.data);  
  67.             };  
  68.         });  
  69.   
  70.         Chat.initialize = function() {  
  71.             if (window.location.protocol == 'http:') {  
  72.                 Chat.connect('ws://' + window.location.host + '/socket2/websocket/chat');  
  73.             } else {  
  74.                 Chat.connect('wss://' + window.location.host + '/socket2/websocket/chat');  
  75.             }  
  76.         };  
  77.   
  78.         Chat.sendMessage = (function() {  
  79.             var message = document.getElementById('chat').value;  
  80.             if (message != '') {  
  81.                 Chat.socket.send(message);  
  82.                 document.getElementById('chat').value = '';  
  83.             }  
  84.         });  
  85.   
  86.         var Console = {};  
  87.   
  88.         Console.log = (function(message) {  
  89.             var console = document.getElementById('console');  
  90.             var p = document.createElement('p');  
  91.             p.style.wordWrap = 'break-word';  
  92.             p.innerHTML = message;  
  93.             console.appendChild(p);  
  94.             while (console.childNodes.length > 25) {   
  95.                 console.removeChild(console.firstChild);  
  96.             }  
  97.             console.scrollTop = console.scrollHeight;  
  98.         });  
  99.   
  100.         Chat.initialize();  
  101.   
  102.   
  103.         document.addEventListener("DOMContentLoaded", function() {  
  104.             // Remove elements with "noscript" class - <noscript> is not allowed in XHTML  
  105.             var noscripts = document.getElementsByClassName("noscript");  
  106.             for (var i = 0; i < noscripts.length; i++) {  
  107.                 noscripts[i].parentNode.removeChild(noscripts[i]);  
  108.             }  
  109.         }, false);  
  110.   
  111.    </script>  
  112. </head>  
  113. <body>  
  114. <div class="noscript"><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websockets rely on Javascript being enabled. Please enable  
  115.     Javascript and reload this page!</h2></div>  
  116. <div>  
  117.     <p>  
  118.         <input type="text" placeholder="请输入内容" id="chat" />  
  119.     </p>  
  120.     <div id="console-container">  
  121.         <div id="console"/>  
  122.     </div>  
  123. </div>  
  124. </body>  
  125. </html>  
可指定发送给某个用户,也可全部发送,详情见ChatAnnotation类的broadcast方法。

程序发布时记得删除tomcat-coyote.jar、tomcat-juli.jar、websocket-api.jar这三个jar包在启动Tomcat。

程序截图,Guest0用户发送信息的信息,在后台进行了判断只发送给自己:


Guest1:

Guest2:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值