• websocket(二)--简单实现网页版群聊


    websocket可以实现服务端的消息推送,而不必在客户端轮询,大大的节省的资源,对于实时通讯来说简直是个大喜讯。

    在上一篇文章中介绍了协议握手,这篇文章将通过实现简单的群聊来帮助进一步了解websocket。

    注意:1.JavaEE版本为7.0

                 2.tomcat版本为8.0 

                 3.不需要额外导入其他的jar包 

                 由于websocket不支持低版本的javaEE和tomcat,所以必须符合上述条件,我是在Myeclipse2014 的IDE中进行编码的。

                 为了尽可能的使代码简洁以便更好的理解,所以代码中有些地方可能不全面,但不影响学习websocket。 

                 首先是WebSocketServer类:

                  

    package socket;
    
    import java.io.IOException;
    import java.util.Set;
    import java.util.concurrent.CopyOnWriteArraySet;
    
    import javax.servlet.http.HttpSession;
    import javax.websocket.EndpointConfig;
    import javax.websocket.OnClose;
    import javax.websocket.OnMessage;
    import javax.websocket.OnOpen;
    import javax.websocket.Session;
    import javax.websocket.server.ServerEndpoint;
    
    @ServerEndpoint(value = "/socket",configurator=GetHttpSessionConfigurator.class)  
    public class WebSocketServer {
    	
    	private static final Set<WebSocketServer> onlineUsers =
                new CopyOnWriteArraySet<WebSocketServer>();  //静态变量 存储在线用户
    	private HttpSession httpSession;
    	private Session session;
    	private String name;
    	
    	@OnMessage  
        public void onMessage(String message, Session session)   
            throws IOException, InterruptedException { 
    	
    		//将客户端传来的消息发送给所有在线用户
    		sendMessageToAllOnline(session,this.name+" : "+message);
    		
    		//在控制台打印当前在线用户
    		for(WebSocketServer webSocketServer:onlineUsers){
            	System.out.print(webSocketServer.name+"  ");
            }
            System.out.println();
        }  
          
        @OnOpen  
        public void onOpen (Session session, EndpointConfig config) throws IOException {  
            System.out.println("Client connected");  
            
            this.session = session;
            this.httpSession = (HttpSession) config.getUserProperties()
                    .get(HttpSession.class.getName());
            this.name=(String) httpSession.getAttribute("name");
            onlineUsers.add(this);   //将用户信息添加到在线用户序列中
            
            //将上线消息发送给所有在线用户
            sendMessageToAllOnline(session,this.name+" 上线了");
            
        }  
      
        @OnClose  
        public void onClose(Session session) throws IOException{  
        	onlineUsers.remove(this);
            System.out.println("Connection closed"); 
            //将下线消息发送给所有在线用户
            sendMessageToAllOnline(session,this.name+" 下线了");
            
        }  
       /**
        * 发送信息给所有在线用户.
        * @param session
        * @param message
        */
       public void sendMessageToAllOnline(Session session,String message) throws IOException{
    	   for (Session sess : session.getOpenSessions()){
    	  		  if (sess.isOpen()){
    	  			  sess.getBasicRemote().sendText(message);			  
    	  		  }
    	   }
       }
    }
    
    由于这里边的session和平时使用的httpsession不是同一个,所以为了可以获取httpsession以便获取当前用户的信息,所以需要下面的类:

    package socket;
    
    import javax.servlet.http.HttpSession;
    import javax.websocket.HandshakeResponse;
    import javax.websocket.server.HandshakeRequest;
    import javax.websocket.server.ServerEndpointConfig;
    /**
     * 为获取httpSession提供支持
     * @author nagsh
     *
     */
    public class GetHttpSessionConfigurator extends ServerEndpointConfig.Configurator{
    	@Override
        public void modifyHandshake(ServerEndpointConfig config,
                                    HandshakeRequest request,
                                    HandshakeResponse response){
            HttpSession httpSession = (HttpSession)request.getHttpSession();
            config.getUserProperties().put(HttpSession.class.getName(),httpSession);
        }
    }
    

    该类在websocket的@ServerEndpoint注解中引用。

    为了可以获取登陆用户的信息以便实现群聊,简单的写了一个登陆,会将用户信息存到session中

    客户端:

    login.html

    <!DOCTYPE html>
    <html>
      <head>
        <title>login.html</title>
      </head>
      
      <body>
        <form action="servlet/LoginServlet" method="post">
                   姓名:<input type="text" name="name"/>
           <input type="submit">
        </form>
      </body>
    </html>
    

    服务端:

    package socket;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    /**
     * 处理用户的登陆.
     * @author nagsh
     *
     */
    public class LoginServlet extends HttpServlet {
    
    	
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		doPost(request, response);
    	}
    
    	
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    
    		response.setContentType("text/html");
    		PrintWriter out = response.getWriter();
    		
    		String name = request.getParameter("name");
    		//将当前用户的信息存入session中
    		request.getSession().setAttribute("name",name);
    		//重定向到聊天界面
    		response.sendRedirect("/websockettest/socketClient.jsp");
    	}
    
    }
    

    然后下面是简单的聊天界面(勿吐槽哈) 该页面是在上篇文章实现握手的页面基础上简单修改的:

    socketClient.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    
    <!DOCTYPE html>
    <html>
    <head>
    <title>Testing websockets</title>
     <script type="text/javascript" src="js/jquery.min.js"></script>
    </head>
    <script type="text/javascript">
    	    /*   申请一个WebSocket对象,参数是需要连接的服务器端的地址 */
    		var webSocket =  new WebSocket('ws://localhost:8080/websockettest/socket');
    
            /* 如果出现连接、处理、接收、发送数据失败的时候就会触发onerror事件 */
    		webSocket.onerror = function(event) {
    			onError(event)
    		};
    		
           /* 当websocket创建成功时,即会触发onopen事件 */
    		webSocket.onopen = function(event) {
    			onOpen(event)
    		};
    		
            /* 当客户端收到服务端发来的消息时,会触发onmessage事件,参数evt.data中包含server传输过来的数据 */
    		webSocket.onmessage = function(event) {
    			onMessage(event)
    		};
    		
            /* 当客户端收到服务端发送的关闭连接的请求时,触发onclose事件 */
            webSocket.onclose = function(event) {
    			onMessage(event)
    		};
    
    		function onMessage(event) {
    		   $("#messages").append(event.data+"<br/>");
    		}
    
    		function onOpen(event) {
    		    $("#messages").append("成功建立连接...<br/>");
    		    $("#messages").append(event.data);
    			
    		}
    
            function onClose(event) {
    			$("#messages").append(event.data);
    		}
    
    		function onError(event) {
    			alert("error");
    		}
    		
            //发送信息
            function send(){
                var content = $("#content").val();
                webSocket.send(content);      
            }
    	</script>
    <body>
    	
    	<div id="messages"></div>
    	<input type="text" id="content">
    	<input type="button" value="发送" onclick="send()">
    	
    </body>
    </html>





    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    vi编辑器更新...
    centos7 修改密码
    Linux的vi编辑器笔记
    linux 基本命令2(12月27日笔记)
    linux 进阶命令笔记(12月26日)
    linux 基础命令(12月25日笔记)
    谈谈CSS3中display属性的Flex布局(弹性布局)
    微信小程序页面跳转的三种方式总结
    微信小程序animation有趣的自定义动画
    微信小程序wx.setStorage(OBJECT)
  • 原文地址:https://www.cnblogs.com/dingxiaoyue/p/4931740.html
Copyright © 2020-2023  润新知