Java webSocket 網頁聊天室

分類:編程 時間:2016-11-08
[摘要:webSocket簡介 webSocket是ajax輪詢取long pull體式格局的革新。ajax輪詢:每隔一段時光要求一次,不論有無新疑息;long pull:每次要求以後,比及有新疑息才會返回;webSocket]

webSocket簡介

webSocket是ajax輪詢與long pull方式的改進。ajax輪詢:每隔一段時間請求一次,不管有沒有新信息;long pull:每次請求之後,等到有新信息才會返回;webSocket:客戶端發送一次請求之後,只要有新信息,服務器就會主動把數據推送過去。

效果截圖

參考了網上的例子來實現聊天室,實驗樓的那個不錯!但是,打開兩個頁面卻不能真正的聊天,後面參考Tomcat下的ChatAnnotation.Java綜合兩者,才有了這個聊天室。

效果圖1:
交互聊天

效果圖2:
用戶下線系統消息

增加代碼

後臺代碼增加以下幾點:

  • 1、在會話打開時,將對應的session添加到對應map中;
  • 2、當發送消息時,遍歷整個map,然後對每個session發送消息;
  • 3、關閉時,將對應的session從map中刪除,不再接收消息,並且如果此用戶有發送過消息,系統將提示該用戶已下線
/**
 * 聊天服務器類
 * 
 * @author yuechang
 *
 */
@ServerEndpoint("/websocket")
public class ChatServer {

    private Session session;
    private static final Map<ChatServer, String> connections = new ConcurrentHashMap<ChatServer, String>();

    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // 日期格式化

    /**
     * @category 添加初始化操作
     * @param session
     */
    @OnOpen
    public void open(Session session) {

        // 開啟會話,將session存入map中,不過此時的nikename存入的為空字符串
        this.session = session;
        connections.put(this, "");
    }

    /**
     * @category 接受客戶端的消息,並把消息發送給所有連接的會話
     * @param message 客戶端發來的消息
     * @param session 客戶端的會話
     */
    @OnMessage
    public void getMessage(String message, Session session) {

        // 把客戶端的消息解析為JSON對象
        JSONObject jsonObject = JSONObject.fromObject(message);
        // 獲得昵稱
        String nikename = (String) jsonObject.get("nickname");
        // 存入map中
        connections.put(this, nikename);
        broadcast(message);
    }

    /**
     * @category 添加關閉會話時的操作
     * @param reason
     */
    @OnClose
    public void close(CloseReason reason) {

        String nikename = connections.get(this);
        // 下線時,得從總人數中移除,否則信息公布時找不到下線的session報錯的
        connections.remove(this);
        // 如果這個人有在聊天室中發過言,則向聊天室中發送nikename已下線消息
        if (StringUtils.isNotBlank(nikename)) {
            String msg = "{'content':'<p>用戶[ ".concat(nikename).concat(" ]下線了!<br/></p>','nickname':'系統消息'}");
            broadcast(msg);// 這是告知所還在線聊天的人下線了
        }
    }

    /**
     * @category 添加處理錯誤的操作
     * @param t
     */
    @OnError
    public void error(Throwable t) {
        // 添加處理錯誤的操作
    }

    /**
     * @category 廣播消息
     * @param msg 消息JSON串
     */
    private void broadcast(String msg) {

        Iterator<ChatServer> iterator = connections.keySet().iterator();
        while (iterator.hasNext()) {
            ChatServer client = iterator.next();
            synchronized (client) {

                // 把客戶端的消息解析為JSON對象
                JSONObject jsonObject = JSONObject.fromObject(msg);
                // 在消息中添加發送日期
                jsonObject.put("date", DATE_FORMAT.format(new Date()));

                // 添加本條消息是否為當前會話本身發的標誌
                jsonObject.put("isSelf", client.session.equals(session));
                // 發送JSON格式的消息
                client.session.getAsyncRemote().sendText(jsonObject.toString());
            }
        }
    }
}

遇到的問題

在Maven項目中,由於web.xml申明的web-app是2.3版本的,不支持JSP內置對象,需要進行web.xml申明為:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">
</web-app>

然後再JSP頁面加上:

<%@ page isELIgnored="false" %>

項目下載地址

https://github.com/yuechang/webSocket.git

博文參考:

  • http://zhihu.com/question/20215561/answer/40316953
  • http://shiyanlou.iteye.com/blog/2182565
  • apache-tomcat-7.0.63\webapps\examples\WEB-INF\classes\websocket\chat\ChatAnnotation.java

Tags: 聊天室 private 效果圖 public 服務器

文章來源:


ads
ads

相關文章
ads

相關文章

ad