zoukankan      html  css  js  c++  java
  • 关于websocket自定义通信,聊天工具--博客园老牛大讲堂

    声明: 我的文章会不断更新的,或许你今天看完后,我第二天就更新了。关注:博客园老牛大讲堂

        关于websocket通信,我也没做过,我也是参考别人的才成功的!今天把文章给补全。参考地址(我也忘了,有空补上)。

        首先jdk1.7和tomact7以上,才能用websocket. 并且需要jar包:websocket-api.jar

    1、什么是websocket通信?

      通信一般应用就是常见的聊天等软件。例如qq,微信等。

    2、websocket有什么作用?

       其实说白了,就是为了进行聊天的,或者实现群聊。如果你能把这一块儿做全了,那么你也可以推出一个聊天工具了。

    3、常见的通信有哪几种?

      通信分类:

        1、现在网上出了很多第三方的通信。个人推荐这种。(毕竟人家的东西已经成熟),用着方便。(第三方通信)

        2、另一种就是andorid原生开发了。应该也是借用第三方的通信(个人表示不清楚)(android通信)

        3、如果你是一个H5用户,又不想借用第三方通信,那么就可以往下面看了。(例如:websocket)。(自定义消息通信)

      补充:

        1、对于android来说,一般用第三方通信:例如极光,融云等平台。

        2、对于H5用户来说,一般也用第三方通信,也可以用websocket。

    4、自定义消息通信怎样实现?(其他两种我就不介绍了)

      接下来我介绍一种推送,它不借助与第三方工具是第三种情况。

      1、MyWebSocket代码:

    package Tools;
    import java.io.IOException
    import java.util.concurrent.CopyOnWriteArraySet;
     
    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;
     
    //该注解用来指定一个URI,客户端可以通过这个URI来连接到WebSocket。类似Servlet的注解mapping。无需在web.xml中配置。---博客园老牛大讲堂
    @ServerEndpoint("/chat")//这里的注释相当于web.xml了,所以可以不用配置web.xml了,当然配置了也不算错
    public class MyWebSocket {
        
        //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。---博客园老牛大讲堂
        private static int onlineCount = 0;
         
        //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
        private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<MyWebSocket>();
         
        //与某个客户端的连接会话,需要通过它来给客户端发送数据---博客园老牛大讲堂
        private Session session;
         
        /**
         * 连接建立成功调用的方法
         * @param session  可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据---博客园老牛大讲堂
         */
        @OnOpen
        public void onOpen(Session session){
            this.session = session;
            webSocketSet.add(this);     //加入set中
            addOnlineCount();           //在线数加1
            System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
            
    //       this.session.getBasicRemote().sendText(HttpServletRequest.getRemoteAddr());---博客园老牛大讲堂
        }
         
        /**
         * 连接关闭调用的方法
         */
        @OnClose
        public void onClose(){
            webSocketSet.remove(this);  //从set中删除
            subOnlineCount();           //在线数减1    
            System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
        }
         
        /**
         * 收到客户端消息后调用的方法
         * @param message 客户端发送过来的消息
         * @param session 可选的参数--博客园老牛大讲堂
         */
        @OnMessage
        public void onMessage(String message, Session session) {
            System.out.println("来自客户端的消息:" + message);
            //群发消息
            for(MyWebSocket item: webSocketSet){             
                try {
                    item.sendMessage(message);
                } catch (IOException e) {
                    e.printStackTrace();
                    continue;
                }
            }
        }
         
        /**
         * 发生错误时调用
         * @param session
         * @param error
         */
        @OnError
        public void onError(Session session, Throwable error){
            System.out.println("发生错误");
            error.printStackTrace();
        }
         
        /**
         * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。--博客园老牛大讲堂
         * @param message
         * @throws IOException
         */
        public void sendMessage(String message) throws IOException{
            this.session.getBasicRemote().sendText(message);
            //this.session.getAsyncRemote().sendText(message);
        }
     
        public static synchronized int getOnlineCount() {
            return onlineCount;
        }
     
        public static synchronized void addOnlineCount() {
            MyWebSocket.onlineCount++;
        }
         
        public static synchronized void subOnlineCount() {
            MyWebSocket.onlineCount--;
        }
    }

      2、前端页面

      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>
    <html>
      <head>
      	<script type="text/javascript" src="js/jquery.min.js"></script>
        <base href="<%=basePath%>">
        <title>My WebSocket</title>
      </head>
       
      <body>
        Welcome<br/>
        <input id="text" type="text" /><button onclick="send()">Send</button>    <button onclick="closeWebSocket()">Close</button>
        <div id="message">
        </div>
      </body>
       
      <script type="text/JavaScript">
          var websocket = null;
           
          //判断当前浏览器是否支持WebSocket
          if('WebSocket' in window){
              websocket = new WebSocket("ws://localhost:8080/MyWebSocket/chat");//这里没有走web.xml,直接到了MyWebSocket
          }
          else{
              alert('Not support websocket');
          }
           
          //连接发生错误的回调方法
          websocket.onerror = function(){
              setMessageInnerHTML("error");
          };
           
          //连接成功建立的回调方法
          websocket.onopen = function(event){
              setMessageInnerHTML("open");
          };
           
          //接收到消息的回调方法
          websocket.onmessage = function(){
              setMessageInnerHTML(event.data);
          };
           
          //连接关闭的回调方法
          websocket.onclose = function(){
              setMessageInnerHTML("close");
          };
           
          //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
          window.onbeforeunload = function(){
              websocket.close();
          };
           
          //将消息显示在网页上
          function setMessageInnerHTML(innerHTML){
              document.getElementById('message').innerHTML += innerHTML + '<br/>';
          }
           
          //关闭连接
          function closeWebSocket(){
              websocket.close();
          }
           
          //发送消息
          function send(){
              var message = document.getElementById('text').value;
              websocket.send(message);
          }
      </script>
      <body>sds</body>
    </html>
    

      3、web.xml可以不配置的(我的没有配置并且成功了)

      注释:如果不成功,给我留言。(稍后我会上传我自己写的一个网页版的群聊软件)

     5、webSocek群聊天工具(改进版)--博客园老牛大讲堂。

      思路:用户都通过键值对的方式进行传递数据和内容。(这样就可以传递不同数据)

         其中 ,是我自己在里面封装的方法,你们可以自己写的。

      这个例子,重要的是一个思路。

      后端代码不变!前端页面部分:--博客园老牛大讲堂

    <!doctype html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0"><meta name="format-detection" content="telephone=no">
        <title>chat</title>
        <link rel="stylesheet" href="../../css/seedsui.min.css">//引入的第三方的css
        <script src="../../js/seedsui.min.js"></script>//引入的第三方的js
        <script type="text/javascript" src="../../js/swiperJs/jquery.min.js" ></script>
        <script type="text/javascript" src="../../js/myJs/check.js" ></script>//自己定义的方法-博客园老牛大讲堂。
        <script type="text/javascript" src="../../js/myJs/jsoup.js" ></script>//自己定义的方法
        <style>
        	.niu-pandding-left-30{
        		padding-left: 30px;
        	}
        	
        	.niu-user-font{
        		font-size: 14px;
        		text-align: center;
        		margin: 15px 40px 15px 0px;
        		float: right;
        	}
        	.niu-huanying{
        		font-size: 14px;
        		text-align: center;
        		margin: 15px 40px 15px 0px;
        	}
        	.niu-button{
        		padding-left: 10px;
        	}
        </style>
    </head>
    //博客园老牛大讲堂
    	<body ontouchstart="">
            <header>
                <div class="titlebar niu-pandding-left-30">
                    <h1>内部讨论组</h1>
                </div>
            </header>
            <article style="padding-bottom:47px;">
            	<p class="niu-user-font" >时间:<span id="shijian">2017-04-24 9:40:26</span></p>
            	<br />
                <ul class="chat" id="niuChat">
                    <li>
                        <div class="chat-photo">
                            <img src="../../img/photo.png" alt="male">
                        </div>
                        <div class="chat-content-box">
                            <div class="chat-content">
                            	<b>用户ID:<span>sadf</span></b>
                                <p>啥?你说滴是啥?那啥啥啥东西啊?咋看不懂啊,你说滴到底是个啥?</p>
                            </div>
                        </div>
                    </li>
                     <li class="even">
                        <div class="chat-photo">
                            <img src="../../img/photo.png" alt="Female">
                        </div>
                        <div class="chat-content-box">
                            <div class="chat-content">
                                <p>啥?你说滴是啥?那啥啥啥东西啊?咋看不懂啊,你说滴到底是个啥?</p>
                            </div>
                        </div>
                    </li>
                </ul>
            </article>
            <footer>
               <div class="inputbox bordered margin8">
               		<a class="button niu-button">请输入内容:</a>
    				<input type="text" class="input-text" id="NiuContent"/>
    				<a class="button lrpadding8" onclick="send()">检验</a>
    			</div>
            </footer>
        
        	<script>
           		
           		var name="老师";
           		
           		//时间初始化模块
           		clearUI();
           		function clearUI(){
           			$("#niuChat").empty();//清空内容
    				setInterval(function(){
    					$("#shijian").html("2016-05-04 14:12:12"));//主要实现显示时间,你也可以自己写个方法,动态的得到时间
    				}, 1000)
           		}
           		
           		var websocket = null;
    		     //判断当前浏览器是否支持WebSocket
    		    if('WebSocket' in window){
    		       websocket = new WebSocket("ws://localhost:8080/SecondWeb/chat");//这个是你后台写的webSocket.
    		    }else{
    		        alert('你的浏览器不支持通信');
    		    }
    		      	
    		    //连接成功建立的回调方法
    			websocket.onopen = function(event){
    			    setTimeout(function(){
           				websocket.send("name:"+name);//发送一句话,key值是name,把用户的名字发送给后台,这样大家都能看到你是谁了。
           			},4000);
          		};
    
    			//接收到消息的回调方法--博客园老牛大讲堂。
    		    websocket.onmessage = function(){
    		      	var value=fenge(event.data);//当服务器有返回值则,自动调用这个方法,event.data是服务器的数据。--博客园老牛大讲堂
    		        //每当我发送消息,成功的话,服务器端就会返回信息,那么我就可以根据key值不同,得到不同的内容了。---- 博客园老牛大讲堂
    		      	if(value[0]=="name"){
    		      		var str=' <p class="niu-huanying">欢迎老师:《<span>'+value[1]+'</span>》进入房间</p><br/>';
    		      		$("#niuChat").append(str);//当这个人进入房间,动态添加数据
    		      	}else if(value[0]=="close"){
    		      		var str=' <p class="niu-huanying">《<span>'+value[1]+'</span>》老师已经离开了房间</p><br>';
    		      		$("#niuChat").append(str);//当老师退出房间,进行提示离开房间
    		      	}
    				else if(value[0]=="closeAll"){
    //		      		console.log(value[0]+value[1]);	
    		      	}
    				else if(value[0]=="content"){
    		      		var str=' <li><div class="chat-photo"><img src="../../img/photo.png" alt="male"></div>'+
                        		'<div class="chat-content-box"><div class="chat-content"><span><'+name+'老师></span></b>'+
                                '<p>'+value[1]+'</p></div></div></li>';
    		      		$("#niuChat").append(str);//当某个用户发送内容,那么本页面进行信息的显示。
    		      	}
    		    };
    		    
    		      //连接关闭的回调方法--博客园老牛大讲堂
    		      websocket.onclose = function(){
    		          websocket.send("close:"+name);
    		      };
    		       
    		      //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    		      window.onbeforeunload = function(){
    		      	websocket.send("close:"+name)//关闭连接,发送key值是close的内容。
    		         websocket.close();
    		      };
    		       
    		      //关闭连接--博客园老牛大讲堂
    		      function closeWebSocket(){
    		      	websocket.send("close:"+name)
    		        websocket.close();
    		      }
    		      
    		      $(document).keydown(function(event){ 
    					if(event.keyCode == 13){ 
    						send();//当我敲击键盘空格键,那么进行发消息的内容。
    					}
    				});
    		      
    		      
    		      //发送消息--博客园老牛大讲堂
    		     function send(){
    		     	var str=$("#NiuContent").val()+"";//进行输入框清空操作。
    		     	if(str!=""){
    		     		$("#NiuContent").val("");
    		     		websocket.send("content:"+str);//向服务器发送内容。
    		     	}else{
    		     		$("#NiuContent").attr("placeholder","内容不能为空");
    		     	}
          		}
    //对key值和value值根据:号进行数据的分割。---博客园老牛大讲堂 function fenge(str){ return str.split(":"); } </script> </body> </html>

      

  • 相关阅读:
    批处理
    命名规则
    注释
    HTML DOM属性
    OLTP
    修改HTML元素
    HTML
    工具资源系列之给虚拟机装个centos
    工具资源系列之给虚拟机装个windows
    工具资源系列之给mac装个虚拟机
  • 原文地址:https://www.cnblogs.com/laonniudajiangtang/p/6514226.html
Copyright © 2011-2022 走看看