今天突然看到了WebSocket然后就網上找了一個例子,然后修改了下,實現了簡單的聊天室,包括群聊和點對點聊天。
使用的代碼如下
jsp代碼:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <base href="<%=basePath%>"> <title>My JSP 'socket.jsp' starting page</title> <meta http-equiv="PRagma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keyWords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/CSS" href="styles.css"> --> <style type="text/css"> input#chat { width: 410px } #console-container { width: 400px; } #console { border: 1px solid #CCCCCC; border-right-color: #999999; border-bottom-color: #999999; height: 170px; overflow-y: scroll; padding: 5px; width: 100%; } #console p { padding: 0; margin: 0; } </style> <script type="application/Javascript"> "use strict"; var Chat = {}; Chat.socket = null; Chat.connect = (function(host) { if ('WebSocket' in window) { Chat.socket = new WebSocket(host); } else if ('MozWebSocket' in window) { Chat.socket = new MozWebSocket(host); } else { Console.log('Error: 瀏覽器不支持WebSocket'); return; } Chat.socket.onopen = function () { Console.log('Info: WebSocket鏈接已打開'); document.getElementById('chat').onkeydown = function(event) { if (event.keyCode == 13) { Chat.sendMessage(); } }; }; Chat.socket.onclose = function () { document.getElementById('chat').onkeydown = null; Console.log('Info: webcocket關閉.'); }; Chat.socket.onmessage = function (message) { Console.log(message.data); }; }); Chat.initialize = function() { if (window.location.protocol == 'http:') { Chat.connect('ws://' + window.location.host + '/gtweb/chat'); } else { Chat.connect('wss://' + window.location.host + '/gtweb/chat'); } }; Chat.sendMessage = (function() { var message = document.getElementById('chat').value; if (message != '') { Chat.socket.send(message); document.getElementById('chat').value = ''; } }); var Console = {}; Console.log = (function(message) { var console = document.getElementById('console'); var p = document.createElement('p'); p.style.wordWrap = 'break-word'; p.innerHTML = message; console.appendChild(p); while (console.childNodes.length > 25) { console.removeChild(console.firstChild); } console.scrollTop = console.scrollHeight; }); Chat.initialize(); document.addEventListener("DOMContentLoaded", function() { // Remove elements with "noscript" class - <noscript> is not allowed in XHTML var noscripts = document.getElementsByClassName("noscript"); for (var i = 0; i < noscripts.length; i++) { noscripts[i].parentNode.removeChild(noscripts[i]); } }, false); </script> </head> <body> <div class="noscript"><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websockets rely on Javascript being enabled. Please enable Javascript and reload this page!</h2></div> <div> <p> <input type="text" placeholder="輸入文字,回車發送" id="chat" /><br> 注意:輸入 消息to用戶名 發送給指定用戶 比如: 你好to用戶1<br> 輸入 消息 直接發送給全體用戶 </p> <div id="console-container"> <div id="console"/> </div> </div> </body></html>后臺代碼:/** * ━━━━━━神獸出沒━━━━━━ * ┏┓ ┏┓ * ┏┛┻━━━┛┻┓ * ┃ ┃ * ┃ ━ ┃ * ┃ ┳┛ ┗┳ ┃ * ┃ ┃ * ┃ ┻ ┃ * ┃ ┃ * ┗━┓ ┏━┛Code is far away from bug with the animal protecting * ┃ ┃ 神獸保佑,代碼無bug * ┃ ┃ * ┃ ┗━━━┓ * ┃ ┣┓ * ┃ ┏┛ * ┗┓┓┏━┳┓┏┛ * ┃┫┫ ┃┫┫ * ┗┻┛ ┗┻┛ * * ━━━━━━感覺萌萌噠━━━━━━ */package gt.controller.admin;import java.io.IOException;import java.util.Set;import java.util.concurrent.CopyOnWriteArraySet;import java.util.concurrent.atomic.AtomicInteger;import javax.websocket.OnClose;import javax.websocket.OnError;import javax.websocket.OnMessage;import javax.websocket.OnOpen;import javax.websocket.session;import javax.websocket.server.ServerEndpoint;import org.springframework.web.bind.annotation.RequestMapping;/** * 類名稱:ChatAnnotation.java 類描述:簡單的聊天室 作 者:why 時 間:2017年3月7日 */@ServerEndpoint(value = "/chat")public class ChatAnnotation { private static final String GUEST_PREFIX = "用戶"; /** * 一個提供原子操作的Integer的類。在Java語言中,++i和i++操作并不是線程安全的, * 在使用的時候,不可避免的會用到synchronized關鍵字。 而AtomicInteger則通過一種線程安全的加減操作接口。 */ private static final AtomicInteger connectionIds = new AtomicInteger(0); private static final Set<ChatAnnotation> connections = new CopyOnWriteArraySet<>(); private final String nickname; private Session session; public ChatAnnotation() { nickname = GUEST_PREFIX + connectionIds.getAndIncrement(); } /** * 創建連接時間調用的方法 * * @param session */ @OnOpen public void start(Session session) { this.session = session; connections.add(this); String message = String.format("* %s %s", nickname, "加入聊天室"); //上線通知 broadcast(message); try { //系統問候語 SendHello(this.nickname); //返回在線用戶 onlineList(); } catch (IOException e) { e.printStackTrace(); } } /** * 鏈接關閉時調用方法 */ @OnClose public void end() { connections.remove(this); String message = String.format("* %s %s", nickname, "退出聊天室"); broadcast(message); } /** * 傳輸信息過程中調用方法 * @param message */ @OnMessage public void incoming(String message) { // Never trust the client // TODO: 過濾輸入的內容 String m = String.format("* %s %s", nickname, message); if(m.contains("to")){ //點對點發送 broadcastOneToOne(m,nickname); }else{ //群發 broadcast(m); } } /** * 發生錯誤是調用方法 * @param t * @throws Throwable */ @OnError public void onError(Throwable t) throws Throwable { System.out.println("錯誤: " + t.toString()); } /** * 消息廣播 * 通過connections,對所有其他用戶推送信息的方法 * @param msg */ private static void broadcast(String msg) { for (ChatAnnotation client : connections) { try { synchronized (client) { client.session.getBasicRemote().sendText(msg); } } catch (IOException e) { System.out.println("錯誤:向客戶端發送消息失敗"); connections.remove(client); try { client.session.close(); } catch (IOException e1) { e1.printStackTrace(); } String message = String.format("* %s %s", client.nickname,"退出聊天室"); broadcast(message); } } } /** * 點對點發送消息 * 通過connections,對所有其他用戶推送信息的方法 * @param msg */ private static void broadcastOneToOne(String msg, String nickName) { String[] arr = msg.split("to"); for (ChatAnnotation client : connections) { try { if(arr[1].equals(client.nickname) || nickName.equals(client.nickname)){ synchronized (client) { client.session.getBasicRemote().sendText(arr[0]); } } } catch (IOException e) { System.out.println("錯誤:向客戶端發送消息失敗"); connections.remove(client); try { client.session.close(); } catch (IOException e1) { e1.printStackTrace(); } String message = String.format("* %s %s", client.nickname,"退出聊天室"); broadcast(message); } } } //系統問候語 private static void SendHello(String nickName) throws IOException{ String m = String.format("* %s %s", nickName, "你好"); for (ChatAnnotation client : connections) { if(client.nickname.equals(nickName)){ client.session.getBasicRemote().sendText(m); } } } //在線用戶 private static void onlineList() throws IOException{ String online = ""; for (ChatAnnotation client : connections) { if(online.equals("")){ online = client.nickname; }else{ online += ","+client.nickname; } } String m = String.format("* %s %s", "當前在線用戶", online); for (ChatAnnotation client : connections) { client.session.getBasicRemote().sendText(m); } }}注釋都加在代碼中了,到此簡單的聊天室就可以使用了。如圖所示。
新聞熱點
疑難解答