java 開發 websocket 網頁端聊天室


博客地址:https://ainyi.com/67

 

WebSocket協議是基於TCP的一種新的網絡協議。它實現了瀏覽器與服務器全雙工(full-duplex)通信——允許服務器主動發送信息給客戶端。

需要導入一個jar包:javax.websocket-api-1.0-rc4.jar

 

注意點:

需要實現這幾個方法:

 1 //注冊事件
 2     ws.onopen = function(){
 3           openWs();
 4     };
 5     ws.onmessage = function(event){
 6            msgWs(event);
 7     };
 8     ws.onclose = function(){
 9           closeWs();
10     };
11     ws.onerror = function(){
12           errorWs();
13     };

 

 

后台代碼:

 1 package com.krry.socket;
 2 import java.io.IOException;
 3 import java.util.concurrent.CopyOnWriteArraySet;
 4  
 5 import javax.websocket.OnClose;
 6 import javax.websocket.OnError;
 7 import javax.websocket.OnMessage;
 8 import javax.websocket.OnOpen;
 9 import javax.websocket.Session;
10 import javax.websocket.server.ServerEndpoint;
11  
12 //該注解用來指定一個URI,客戶端可以通過這個URI來連接到WebSocket。類似Servlet的注解mapping。無需在web.xml中配置。
13 @ServerEndpoint("/websocket")
14 public class MyWebSocket {
15     //靜態變量,用來記錄當前在線連接數。應該把它設計成線程安全的。
16     private static int onlineCount = 0;
17      
18     //concurrent包的線程安全Set,用來存放每個客戶端對應的MyWebSocket對象。若要實現服務端與單一客戶端通信的話,可以使用Map來存放,其中Key可以為用戶標識
19     private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<MyWebSocket>();
20      
21     //與某個客戶端的連接會話,需要通過它來給客戶端發送數據
22     private Session session;
23      
24     /**
25      * 連接建立成功調用的方法
26      * @param session  可選的參數。session為與某個客戶端的連接會話,需要通過它來給客戶端發送數據
27      */
28     @OnOpen
29     public void onOpen(Session session){
30         this.session = session;
31         webSocketSet.add(this);     //加入set中
32         addOnlineCount();           //在線數加1
33         System.out.println("有新連接加入!當前在線人數為" + getOnlineCount());
34     }
35      
36     /**
37      * 連接關閉調用的方法
38      */
39     @OnClose
40     public void onClose(){
41         webSocketSet.remove(this);  //從set中刪除
42         subOnlineCount();           //在線數減1    
43         System.out.println("有一連接關閉!當前在線人數為" + getOnlineCount());
44     }
45      
46     /**
47      * 收到客戶端消息后調用的方法
48      * @param message 客戶端發送過來的消息
49      * @param session 可選的參數
50      */
51     @OnMessage
52     public void onMessage(String message, Session session) {
53         System.out.println("來自客戶端的消息:" + message);
54          
55         //群發消息
56         for(MyWebSocket item: webSocketSet){             
57             try {
58                 item.sendMessage(message);
59             } catch (IOException e) {
60                 e.printStackTrace();
61                 continue;
62             }
63         }
64     }
65      
66     /**
67      * 發生錯誤時調用
68      * @param session
69      * @param error
70      */
71     @OnError
72     public void onError(Session session, Throwable error){
73         System.out.println("發生錯誤");
74         error.printStackTrace();
75     }
76      
77     /**
78      * 這個方法與上面幾個方法不一樣。沒有用注解,是根據自己需要添加的方法。
79      * @param message
80      * @throws IOException
81      */
82     public void sendMessage(String message) throws IOException{
83         this.session.getBasicRemote().sendText(message);
84         //this.session.getAsyncRemote().sendText(message);
85     }
86  
87     public static synchronized int getOnlineCount() {
88         return onlineCount;
89     }
90  
91     public static synchronized void addOnlineCount() {
92         MyWebSocket.onlineCount++;
93     }
94      
95     public static synchronized void subOnlineCount() {
96         MyWebSocket.onlineCount--;
97     }
98 }

 

前端代碼:

  1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
  2 <!doctype html>
  3 <html>
  4     <head>
  5         <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
  6         <meta name="keywords" content="">
  7         <meta name="description" content="">
  8         <title>基於Java服務器端的消息主動推送技術揭秘 --krry</title>
  9         <link rel="stylesheet" href="css/animate.css"/>
 10         <link rel="stylesheet" type="text/css" href="css/sg.css" />
 11         <style>
 12             *{margin:0;padding:0;}
 13             body{background:url("images/5.jpg");background-size:cover;}
 14             h1{margin-top:50px;text-align:center;color:#fff;text-shadow:1px 1px 1px #000;font-family:-webkit-body;font-size:24px;}
 15             .box{width:700px;margin:20px auto;}
 16             .box span{color:#f60;font-size:16px;font-family:"微軟雅黑";}
 17             .box .shu{text-indent:1em;height:24px;font-family:"微軟雅黑";border:0;outline:none;font-size:14px;}
 18             .box .add{width:300px;margin-right:24px;}
 19             .box .user{width:200px;}
 20             .box .btn{width:80px;height:34px;color:#fff;background:#6c0;border:0;outline:none;cursor:pointer;margin-top:20px;font-size:16px;font-family:"微軟雅黑";}
 21             .box .area{line-height: 29px;height:280px;width:680px;padding:10px;overflow:auto;font-size:16px;font-family:"微軟雅黑";margin:20px 0;outline:none;box-shadow:1px 2px 18px #000}
 22             .box .setex{text-indent:1em;height:28px;border:1px solid #6c0;width:618px;outline:none;float:left;font-family:"微軟雅黑";}
 23             .box .send{font-size:14px;width:80px;height:30px;color:#fff;background:#6c0;border:0;outline:none;cursor:pointer;font-family:"微軟雅黑";}
 24         </style>
 25     </head>
 26     <body>
 27         <h1>基於Java服務器端的消息主動推送技術揭秘 --krry</h1>
 28         <div class="box">
 29             <span>服務器地址:</span><input type="text" class="shu add" value="localhost/krry_NetChat/websocket" readonly/>
 30             <span>用戶名:</span><input type="text" class="shu user" value="匿名"/>
 31             <input type="button" value="連接" class="btn" />
 32             <div class="area" id="boxx"></div>
 33             <div class="c_cen">
 34                 <input type="text" class="setex"/>
 35                 <input type="button" value="發送" class="send">
 36             </div>
 37         </div>
 38         <script src="js/jquery-1.11.1.min.js"></script>
 39         <script src="js/sg.js"></script>
 40         <script src="js/sgutil.js"></script>
 41         <script>
 42             var close = true;
 43             var ws;
 44             $(function(){
 45                 $(".c_cen").hide();
 46                 //首先判斷瀏覽器是否支持webSocket,支持h5的瀏覽器才會支持
 47                 if(window.WebSocket){
 48                     printMsg("您的瀏覽器支持WebSocket,您可以嘗試連接到聊天服務器!","OK");
 49                 }else{
 50                     printMsg("您的瀏覽器不支持WebSocket,請選擇其他瀏覽器!","ERROR");
 51                     //設置按鈕不可點擊
 52                     $(".btn").attr("disabled","true");
 53                 }
 54             });
 55             //打印信息
 56             function printMsg(msg,msgType){
 57                 if(msgType == "OK"){
 58                     msg = "<span style='color:green'>"+msg+"</span>";
 59                 }
 60                 if(msgType == "ERROR"){
 61                     msg = "<span style='color:red'>"+msg+"</span>";
 62                 }
 63                 $(".area").append(msg+"<br/>");
 64                 var boxx = document.getElementById("boxx");
 65                 boxx.scrollTop = boxx.scrollHeight;//使滾動條一直在底部
 66             }
 67             
 68             //打開Socket
 69             function openWs(){
 70                 printMsg("鏈接已建立","OK");
 71                 ws.send(""+$(".user").val()+"】已進入聊天室");
 72                 $(".c_cen").show();
 73             }
 74             
 75             //接收消息的時候
 76             function msgWs(e){
 77                 printMsg(e.data);
 78             }
 79             //關閉連接
 80             function closeWs(){
 81                 $(".btn").val("連接");
 82                 $(".c_cen").hide();
 83             }
 84             //產生錯誤
 85             function errorWs(){
 86                 printMsg("您與服務器連接錯誤...","ERROR");
 87             }
 88 
 89             //點擊發送按鈕
 90             $(".send").click(function(){
 91                 var text = $(".setex").val();
 92                 if(text == null || text == "") return;
 93                 $(".setex").val("");
 94                 ws.send(""+$(".user").val()+"】:"+text);
 95             });
 96             
 97             //點擊連接
 98             $(".btn").click(function(){
 99                 if($(".add").val() && $(".user").val()){
100                     if(close){
101                         printMsg("正在准備連接服務器,請稍等...");
102                         var url = "ws://"+$(".add").val();
103                         if("WebSocket" in window){
104                             ws = new WebSocket(url);
105                         }else if("MozWebSocket" in window){
106                             ws = new MozWebSocket(url);
107                         }
108                         //已連接
109                         $(".btn").val("斷開");
110                         close = false;
111                         
112                         //注冊事件
113                         ws.onopen = function(){
114                             openWs();
115                         };
116                         ws.onmessage = function(event){
117                             msgWs(event);
118                         };
119                         ws.onclose = function(){
120                             closeWs();
121                         };
122                         ws.onerror = function(){
123                             errorWs();
124                         };
125                         
126                         //監聽窗口關閉事件,當窗口關閉時,主動去關閉websocket連接,防止連接還沒斷開就關閉窗口,server端會拋異常。
127                         window.onbeforeunload = function(){
128                             ws.send(""+$(".user").val()+"】離開了聊天室");
129                             close = true;
130                             ws.close();
131                         };
132                         
133                     }else{
134                         ws.send(""+$(".user").val()+"】離開了聊天室");
135                         close = true;
136                         ws.close();
137                     }
138                 }else{
139                     $.tmDialog.alert({open:"left",content:"服務器地址和用戶名不能為空哦...",title:"提示哦~~~"});
140                 }
141             });
142             
143             //回車鍵
144             $(".setex").keypress(function(event){
145                 if(event.keyCode == 13){
146                     $(".send").trigger("click");
147                 }
148             });
149         </script>
150     </body>
151 </html>

 

 

 

 

博客地址:https://ainyi.com/67

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM