今天突然看到了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); } }}注释都加在代码中了,到此简单的聊天室就可以使用了。如图所示。
新闻热点
疑难解答