zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    对技术的研究就是对世界的理解
    程序员的方向
    程序员的分类
    设置tomcat的catalina_home引发的问题
    关于用osgModeling批量生成管道
    Cocos2d-X学习之Ref类
    ApiDemos示例学习(2)——App->Activity->Animation
    ApiDemos示例学习(1)——ApiDemos示例的导入
    eclipse中调出android sdk manager和android virtual device manager图标
    Mono For Android中AlarmManager的使用
  • 原文地址:https://www.cnblogs.com/ainyi/p/8592226.html
Copyright © 2011-2022 走看看