JavaEE7 HTML5利用WebSocket实现即时通讯

HTML5给Web浏览器带来了全双工TCP连接websocket标准服务器的能力。

换句话说,浏览器能够与服务器建立连接,通过已建立的通信信道来发送和接收数据而不需要由HTTP协议引入额外其他的开销来实现。

在本教程中我们将在Java EE环境下实现一个简单的websockect服务器端来和客户端进行数据交互。

本教程需要以下环境:

  1. JDK 1.7.0.21
  2. tomcat 7
: Java EE 7中才引入了WebSocket。

WebSocket服务器端

WebSocketServer 代码:
package com.bing.biz.websocket;

import java.io.IOException;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

 
//该注解用来指定一个URI,客户端可以通过这个URI来连接到WebSocket。类似Servlet的注解mapping。无需在web.xml中配置。
@ServerEndpoint("/webSocketServer/{userId}")
public class WebSocketServer {
     
    /**
     * 连接建立成功调用的方法
     * @param session  可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
     * @throws IOException 
     */
    @OnOpen
    public void onOpen(@PathParam("userId") String userId,Session session) throws IOException{
       /* if(userId!=null){            
            if(!SocketUtils.hasConnection(userId)){
                SocketUtils.put(userId,session);
            }
            else{
                //相同用户只允许在一个地方登录(网页版内部判断)。
                SocketUtils.sendMessage(userId,"forcelogout","该用户已在其他地方登录,此次登录将被强制退出。",0,"");  
                SocketUtils.remove(userId,session.getId());
                SocketUtils.put(userId,session);
            }
        }*/
        System.out.println("Client connected  "+userId);
    }
     
    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam("userId") String userId,Session session)throws IOException{
        //SocketUtils.remove(userId,session.getId());
        System.out.println("Connection closed");
    }
     
    /**
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     * @param session 可选的参数
     * @throws IOException 
     */
    @OnMessage
    public void onMessage(@PathParam("userId") String userId,String message, Session session) throws IOException {
        // Print the client message for testing purposes
        System.out.println("Received: " + message);
       
        // Send the first message to the client
        session.getBasicRemote().sendText("This is the first server message");
       
        // Send 3 messages to the client every 5 seconds
        int sentMessages = 0;
        while(sentMessages < 3){
          session.getBasicRemote().
            sendText("This is an intermediate server message. Count: "
              + sentMessages);
          sentMessages++;
        }
       
        // Send a final message to the client
        session.getBasicRemote().sendText("This is the last server message");
    }
     
    /**
     * 发生错误时调用
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error){
        error.printStackTrace();
    }
}

你可能已经注意到我们从 javax.websocket包中引入了一些类。

@ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端。注解的值将被用于监听用户连接的终端访问URL地址。

onOpen 和 onClose 方法分别被@OnOpen@OnClose 所注解。这两个注解的作用不言自明:他们定义了当一个新用户连接和断开的时候所调用的方法。

onMessage 方法被@OnMessage所注解。这个注解定义了当服务器接收到客户端发送的消息时所调用的方法。注意:这个方法可能包含一个javax.websocket.Session可选参数(在我们的例子里就是session参数)。如果有这个参数,容器将会把当前发送消息客户端的连接Session注入进去。

本例中我们仅仅是将客户端消息内容打印出来,然后首先我们将发送一条开始消息,之后间隔5秒向客户端发送1条测试消息,共发送3次,最后向客户端发送最后一条结束消息。

 

WebSocket客户端

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>
<title>Testing websockets</title>
</head>
<body>
    <div>
        <input type="submit" value="Start" onclick="start()" />
    </div>
    <div id="messages"></div>
    <script type="text/javascript">
    //建立websocket连接
     var websocket = new WebSocket('ws://localhost:8080/bing/webSocketServer/bing');
       
       websocket.onopen = function (evnt) {
           document.getElementById('messages').innerHTML
           = 'Connection established';
       };
       websocket.onmessage = function (evnt) {
           document.getElementById('messages').innerHTML
           += '<br />' + event.data;
       };
       websocket.onerror = function (evnt) {
       };
       websocket.onclose = function (evnt) {
       };
 
    function start() {
      websocket.send('hello');
      return false;
    }
  </script>
</body>
</html>

这是一个简单的页面,包含有JavaScript代码,这些代码创建了一个websocket连接到websocket服务器端。

onOpen 我们创建一个连接到服务器的连接时将会调用此方法。

onError 当客户端-服务器通信发生错误时将会调用此方法。

onMessage 当从服务器接收到一个消息时将会调用此方法。在我们的例子中,我们只是将从服务器获得的消息添加到DOM。

我们连接到websocket 服务器端,使用构造函数 new WebSocket() 而且传之以端点URL:

ws://localhost:8080/bing/webSocketServer/bing  ---bing 后台的userid

 

测试

现在我们可以访问测试页面对我们的应用进行测试:

http://localhost:8080/bing/index.jsp

后台:

 

 

 

posted @ 2016-11-22 14:55  长东  阅读(4972)  评论(0编辑  收藏  举报