日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

《java websocket》之 实现

發(fā)布時(shí)間:2023/12/16 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《java websocket》之 实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

上一篇《java websocket》之 描述篇介紹了一下websocket,那么這一次就自己動手搭建一個屬于自己的websocket。

真的挺簡單的

環(huán)境描述:java jdk1.7+tomcat7.0x

第一步。創(chuàng)建一個干凈的web project工程:

第二步。然后導(dǎo)入我們所用到的包:

第三步。創(chuàng)建一個websocket類用來實(shí)現(xiàn)接口,在創(chuàng)建一個POOL類用來擴(kuò)展業(yè)務(wù)

廢話不說直接上代碼,相信我,我提供的代碼直接復(fù)制進(jìn)去就可以用!

WebSocket 類:

package websocket; import java.net.InetSocketAddress; import java.net.UnknownHostException;import org.java_websocket.handshake.ClientHandshake; import org.java_websocket.server.WebSocketServer;public class WebSocket extends WebSocketServer {public WebSocket(InetSocketAddress address) {super(address);System.out.println("地址"+address);}public WebSocket(int port) throws UnknownHostException {super(new InetSocketAddress(port));System.out.println("端口"+port);}/*** 觸發(fā)關(guān)閉事件*/@Overridepublic void onClose(org.java_websocket.WebSocket conn, int message,String reason, boolean remote) {userLeave(conn);}/*** 觸發(fā)異常事件*/@Overridepublic void onError(org.java_websocket.WebSocket conn, Exception message) {System.out.println("Socket異常:"+message.toString());e++;}/*** 客戶端發(fā)送消息到服務(wù)器時(shí)觸發(fā)事件*/int j=0;int h=0;int e=0;int l=0;@Overridepublic void onMessage(org.java_websocket.WebSocket conn, String message) {message = message.toString();if(message!=null){//將用戶加入this.userjoin(message.toString(), conn);}}/*** 觸發(fā)連接事件*/@Overridepublic void onOpen(org.java_websocket.WebSocket conn, ClientHandshake handshake) {System.out.println("有人連接Socket conn:"+conn);l++;}/*** 用戶加入處理* @param user*/public void userjoin(String user, org.java_websocket.WebSocket conn) {WebSocketPool.sendMessage(user); // 把當(dāng)前用戶加入到所有在線用戶列表中String joinMsg = "[系統(tǒng)]"+user+"上線了!";WebSocketPool.sendMessage(joinMsg); // 向所有在線用戶推送當(dāng)前用戶上線的消息WebSocketPool.addUser(user, conn); // 向連接池添加當(dāng)前的連接對象WebSocketPool.sendMessageToUser(conn, WebSocketPool.getOnlineUser().toString()); // 向當(dāng)前連接發(fā)送當(dāng)前在線用戶的列表}/*** 用戶下線處理* @param user*/public void userLeave(org.java_websocket.WebSocket conn) {String user = WebSocketPool.getUserByKey(conn);boolean b = WebSocketPool.removeUser(conn); // 在連接池中移除連接if (b) {WebSocketPool.sendMessage(user.toString()); // 把當(dāng)前用戶從所有在線用戶列表中刪除String joinMsg = "[系統(tǒng)]"+user+"下線了";WebSocketPool.sendMessage(joinMsg); // 向在線用戶發(fā)送當(dāng)前用戶退出的消息}} }

WebSocketPool 類:

package websocket; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.java_websocket.WebSocket;public class WebSocketPool {private static final Map<WebSocket, String> userconnections = new HashMap<WebSocket, String>();/*** 獲取用戶名* @param session*/public static String getUserByKey(WebSocket conn) {return userconnections.get(conn);}/*** 獲取在線總數(shù)* @param*/public static int getUserCount() {return userconnections.size();}/*** 獲取WebSocket* @param user*/public static WebSocket getWebSocketByUser(String user) {Set<WebSocket> keySet = userconnections.keySet();synchronized (keySet) {for (WebSocket conn : keySet) {String cuser = userconnections.get(conn);if (cuser.equals(user)) {return conn;}}}return null;}/*** 向連接池中添加連接* @param inbound*/public static void addUser(String user, WebSocket conn) {userconnections.put(conn, user); // 添加連接}/*** 獲取所有的在線用戶* @return*/public static Collection<String> getOnlineUser() {List<String> setUsers = new ArrayList<String>();Collection<String> setUser = userconnections.values();for (String u : setUser) {setUsers.add(u);}return setUsers;}/*** 移除連接池中的連接* @param inbound*/public static boolean removeUser(WebSocket conn) {if (userconnections.containsKey(conn)) {userconnections.remove(conn); // 移除連接return true;} else {return false;}}/*** 向特定的用戶發(fā)送數(shù)據(jù)* @param user* @param message*/public static void sendMessageToUser(WebSocket conn, String message) {if (null != conn) {conn.send(message);}}/*** 向所有的用戶發(fā)送消息* @param message*/public static void sendMessage(String message) {Set<WebSocket> keySet = userconnections.keySet();synchronized (keySet) {for (WebSocket conn : keySet) {String user = userconnections.get(conn);if (user != null) {conn.send(message);}}}} }

然后讓我們先測試一下是否行得通:

所以我在WebSocket 類里面寫一個main方法來啟動websocket服務(wù):

public static void main(String[] args) throws InterruptedException {System.out.println("開始啟動websocket");WebSocketImpl.DEBUG = false;int port = 8888; // 端口隨便設(shè)置,只要不跟現(xiàn)有端口重復(fù)就可以WebSocket s = null;try {s = new WebSocket(port);} catch (UnknownHostException e) {System.out.println("啟動websocket失敗!");e.printStackTrace();}s.start();System.out.println("啟動websocket成功!");}

啟動成功后的樣子


然后去http://www.blue-zero.com/websocket/ WebSocket在線測試
輸入地址跟端口后,點(diǎn)擊鏈接


那么到了這一步就說明你的websocket 已經(jīng)搭建好了哦!恭喜你。

下面跟著作者把配置好的websocket實(shí)際應(yīng)用到項(xiàng)目中。

第一步:技術(shù)點(diǎn)為:項(xiàng)目啟動的時(shí)候啟動配置好的服務(wù)。

因?yàn)閱禹?xiàng)目就要開啟websocket服務(wù)保持長連接狀態(tài)。所以我們找到了web.xml,注意必須是3.0以上的

<?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"><display-name></display-name> <filter><filter-name>startFilter</filter-name><filter-class>filter.startFilter</filter-class></filter><servlet> <servlet-name>TestServlet</servlet-name> <servlet-class>servlet.TestServlet</servlet-class> </servlet><servlet-mapping><servlet-name>TestServlet</servlet-name><url-pattern>/TestServlet</url-pattern></servlet-mapping><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list> </web-app>

創(chuàng)建startFilter (原諒我忘記大寫開頭,自己以打自己臉3次),以及TestServlet(不懂Servlet出門百度)

package filter;import java.io.IOException; import java.net.UnknownHostException;import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse;import org.java_websocket.WebSocketImpl;import websocket.WebSocket;/*** 創(chuàng)建人:曉楓 創(chuàng)建時(shí)間:2014年8月18日* @version*/ public class startFilter implements Filter {/*** 初始化*/public void init(FilterConfig fc) throws ServletException {this.startWebsocketOnline();}/*** 啟動socket服務(wù)*/public void startWebsocketOnline() {System.out.println("開始啟動websocket");WebSocketImpl.DEBUG = false;int port = 8888; // 端口隨便設(shè)置,只要不跟現(xiàn)有端口重復(fù)就可以WebSocket s = null;try {s = new WebSocket(port);s.start();} catch (UnknownHostException e) {System.out.println("啟動websocket失敗!");e.printStackTrace();}System.out.println("啟動websocket成功!");}public void destroy() {// TODO Auto-generated method stub}public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException {// TODO Auto-generated method stub}}

細(xì)心地學(xué)者已經(jīng)發(fā)現(xiàn),實(shí)際上就是把main方法里面的代碼拿過來了,霍哇啊哈哈哈哈哈哈!

TestServlet 類

package servlet;import java.io.IOException;import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;public class TestServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {// TODO Auto-generated method stubsuper.doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {System.out.println("content"+req.getParameter("content"));req.getSession().setAttribute("content", req.getParameter("content"));req.getRequestDispatcher("/index.jsp").forward(req, resp);} }

到了這一步就基本服務(wù)端已經(jīng)基本搭建好了。那么開始前臺。技術(shù)為jsp頁面+js

index.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>曉楓的WebSocket</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"><script type="text/javascript" src="js/websocket.js"></script></head><body><input type="hidden" value="${content }" id="content"><form action="TestServlet" method="post">content : <input type="text" name="content"><button type="submit">登陸</button></form><span id="span"></span></body> </html>

就簡單的畫了幾個框框

(廢話:?大部分人都有個毛病,就是功能做一半就會被別的事情所打擾,導(dǎo)致事情拖延,然后加班。就比如一個簡單的頁面就可以測試,非要寫的那么華麗!作者我不管在哪個公司,很少加班,因?yàn)槭呛笈_,界面的好看與否,本身不算到工作量里面。達(dá)到目的就可以。如果嫌棄丑會再給你時(shí)間改的,不會加班)

websocket.js

/*** 申請一個WebSocket對象,參數(shù)是需要連接的服務(wù)器端的地址,* 同http協(xié)議使用http://開頭一樣,* WebSocket協(xié)議的URL使用ws://開頭,* 另外安全的WebSocket協(xié)議使用wss://開頭* 創(chuàng)建人:曉楓 創(chuàng)建時(shí)間 2016-8-18*/ var ws = new WebSocket("ws://127.0.0.1:8888"); ws.onopen = function()//當(dāng)websocket創(chuàng)建成功時(shí),即會觸發(fā)onopen事件 { var content=document.getElementById("content").value;if(content==nullcontent==""){ws.send("XiaoFeng");//用于叫消息發(fā)送到服務(wù)端 注:此處為用戶名}else{ws.send(content);} }; ws.onmessage = function(evt)//當(dāng)客戶端收到服務(wù)端發(fā)來的消息時(shí),會觸發(fā)onmessage事件,參數(shù)evt.data中包含server傳輸過來的數(shù)據(jù) {document.getElementById("span").innerHTML="當(dāng)前在線人數(shù)為:"+evt.data; }; ws.onclose = function(evt)//當(dāng)客戶端收到服務(wù)端發(fā)送的關(guān)閉連接的請求時(shí),觸發(fā)onclose事件 {alert("WebSocketClosed!"); }; ws.onerror = function(evt)//如果出現(xiàn)連接,處理,接收,發(fā)送數(shù)據(jù)失敗的時(shí)候就會觸發(fā)onerror事件 {alert("WebSocketError!"); };

到這里就可以結(jié)束了。
下面正式展示一下



我們打開多個頁面來模仿多人連接.


我們輸入一個內(nèi)容

點(diǎn)擊登錄

已經(jīng)可以看到這個用戶信息添加到Map了
同時(shí),別的頁面也收到了提示消息!

那么到這里就基本結(jié)束了。
強(qiáng)制下線就是把連接移除掉,并且通知你的logout方法就可以了。
只能一個人登陸的話,就判斷一下Map里面是否有用戶就OK了!
實(shí)例就在這里,注釋也都有,自己開腦洞吧。

支持單聊哦!方法已經(jīng)寫好了在Pool.自己發(fā)現(xiàn)吧

到這里開始要開始研究高并發(fā)了,可能會穿插一些spring實(shí)現(xiàn)之類的,看情況吧。

(下面看不看吧,壓力測試一下)

在線測試的網(wǎng)站可以下載壓力測試工具

然后稍微的修改一下代碼。

然后啟動服務(wù)器,清空控制臺,設(shè)置好5000個客戶端同時(shí)連接,連接成功后發(fā)送“1”,項(xiàng)目接收到后回復(fù)“2”,也就是說發(fā)送次數(shù)到為 連接數(shù)X2 的時(shí)候?yàn)橐粋€不丟失, 越接近越好。

開始戰(zhàn)斗吧!

額。。。。。。。。。。。。。。。。。。。。

呵呵。


作者: 手插口袋_?
鏈接:http://www.imooc.com/article/12401
來源:慕課網(wǎng)

總結(jié)

以上是生活随笔為你收集整理的《java websocket》之 实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。