日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
用JavaEE7、Websockets和GlassFish4打造聊天室(一)

Java EE 7已經(jīng)在今年正式發(fā)布了,新增加了很多新的功能和特性,如新增或更新了不少的JSR標(biāo)準(zhǔn)。其中特別受到關(guān)注的是Websockets。它的一個好處之一是減少了不必要的網(wǎng)絡(luò)流量。它主要是用于在客戶機和服務(wù)器之間建立單一的雙向連接。這意味著客戶只需要發(fā)送一個請求到服務(wù)端,那么服務(wù)端則會進行處理,處理好后則將其返回給客戶端,客戶端則可以在等待這個時間繼續(xù)去做其他工作,整個過程是異步的。在本系列教程中,將指導(dǎo)用戶如何在JAVA EE 7的容器GlassFish 4中,使用JAVA EE 7中的全新的解析Json API(JSR-353),以及綜合運用jQuery和Bootstrap。本文要求讀者有一定的HTML 5 Websocket的基礎(chǔ)原理知識。

按需定制設(shè)計可以根據(jù)自己的需求進行定制,成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)構(gòu)思過程中功能建設(shè)理應(yīng)排到主要部位公司成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)的運用實際效果公司網(wǎng)站制作網(wǎng)站建立與制做的實際意義

效果圖

我們先來看下在完成這個教程后的效果圖,如下所示:

準(zhǔn)備工作

我們使用的是JDK 7 和MAVN 3進行庫的構(gòu)建工作,首先看pom.xml中關(guān)于Jave EE 7的部分:

 
 
 
 
  1.  
  2.     ${project.build.directory}/endorsed
  3.     UTF-8
  4.  
  5.     
  6.         javax
  7.         javaee-api
  8.         7.0
  9.         provided
  10.     
  11.  
  12.     
  13.         
  14.             org.apache.maven.plugins
  15.             maven-compiler-plugin
  16.             3.1
  17.             
  18.                 1.7
  19.                 1.7
  20.                 
  21.                     ${endorsed.dir}
  22.                 
  23.             
  24.         
  25.         
  26.             org.apache.maven.plugins
  27.             maven-war-plugin
  28.             2.3
  29.             
  30.                 false
  31.             
  32.         
  33.         
  34.             org.apache.maven.plugins
  35.             maven-dependency-plugin
  36.             2.6
  37.             [..]
  38.         
  39.     

同時,為了能使用GlassFish 4,需要增加如下的插件:

 
 
 
 
  1. plugin>
  2.     org.glassfish.embedded
  3.     maven-embedded-glassfish-plugin
  4.     4.0
  5.     
  6.         embedded-glassfish
  7.         ${basedir}/target/${project.artifactId}-${project.version}.war
  8.         true
  9.         8080
  10.         ${project.artifactId}
  11.         hascode
  12.     
  13.     
  14.         
  15.             
  16.                 deploy
  17.             
  18.         
  19.     

設(shè)置Websocket的Endpoint

我們先來看服務(wù)端Websocket的代碼如下,然后再做進一步解析:

 
 
 
 
  1. package com.hascode.tutorial;
  2.  
  3. import java.io.IOException;
  4. import java.util.logging.Level;
  5. import java.util.logging.Logger;
  6.  
  7. import javax.websocket.EncodeException;
  8. import javax.websocket.OnMessage;
  9. import javax.websocket.OnOpen;
  10. import javax.websocket.Session;
  11. import javax.websocket.server.PathParam;
  12. import javax.websocket.server.ServerEndpoint;
  13.  
  14. @ServerEndpoint(value = "/chat/{room}", encoders = ChatMessageEncoder.class, decoders = ChatMessageDecoder.class)
  15. public class ChatEndpoint {
  16.     private final Logger log = Logger.getLogger(getClass().getName());
  17.  
  18.     @OnOpen
  19.     public void open(final Session session, @PathParam("room") final String room) {
  20.         log.info("session openend and bound to room: " + room);
  21.         session.getUserProperties().put("room", room);
  22.     }
  23.  
  24.     @OnMessage
  25.     public void onMessage(final Session session, final ChatMessage chatMessage) {
  26.         String room = (String) session.getUserProperties().get("room");
  27.         try {
  28.             for (Session s : session.getOpenSessions()) {
  29.                 if (s.isOpen()
  30.                         && room.equals(s.getUserProperties().get("room"))) {
  31.                     s.getBasicRemote().sendObject(chatMessage);
  32.                 }
  33.             }
  34.         } catch (IOException | EncodeException e) {
  35.             log.log(Level.WARNING, "onMessage failed", e);
  36.         }
  37.     }
  38. }

#p#

面分析下上面的代碼:

使用@ ServerEndpoint定義一個新的endpoint,其中的值指定了URL并且可以使用PathParams參數(shù),就象在JAX-RS中的用法一樣。

所以值“/chat/{room}”允許用戶通過如下形式的URL去連接某個聊天室:ws://0.0.0.0:8080/hascode/chat/java

在大括號中的值(即room),可以通過使用javax.websocket.server.PathParam,在endpoint的生命周期回調(diào)方法中以參數(shù)的方式注入。

此外,我們要使用一個編碼和解碼的類,因為我們使用的是一個DTO形式的類,用于在服務(wù)端和客戶端傳送數(shù)據(jù)。

當(dāng)用戶第一次連接到服務(wù)端,輸入要進入聊天室的房號,則這個房號以參數(shù)的方式注入提交,并且使用session.getUserProperties將值保存在用戶的屬性map中。

當(dāng)一個聊天參與者通過tcp連接發(fā)送信息到服務(wù)端,則循環(huán)遍歷所有已打開的session,每個session被綁定到指定的聊天室中,并且接收編碼和解碼的信息。

如果我們想發(fā)送簡單的文本信息或和二進制格式的信息,則可以使用session.getBasicRemote().sendBinary() 或session.getBasicRemote().sendText()

接下來我們看下用于代表信息傳遞實體(DTO:Data Transfer Object)的代碼,如下:

 
 
 
 
  1. package com.hascode.tutorial;
  2.  
  3. import java.util.Date;
  4.  
  5. public class ChatMessage {
  6.     private String message;
  7.     private String sender;
  8.     private Date received;
  9.  
  10.     // 其他getter,setter方法
  11. }

聊天消息的轉(zhuǎn)換

在這個應(yīng)用中,將編寫一個編碼和解碼類,用于在聊天信息和JSON格式間進行轉(zhuǎn)換。

先來看下解碼類的實現(xiàn),這將會把傳遞到服務(wù)端的聊天信息轉(zhuǎn)換為ChatMessage實體類。在這里,使用的是Java API for JSON Processing(JSR353)(參考:

http://jcp.org/en/jsr/detail?id=353)規(guī)范去將JSON格式的信息轉(zhuǎn)換為實體類,代碼如下,其中重寫的willDecode方法,這里默認返回為true。

 
 
 
 
  1. package com.hascode.tutorial;
  2.  
  3. import java.io.StringReader;
  4. import java.util.Date;
  5.  
  6. import javax.json.Json;
  7. import javax.json.JsonObject;
  8. import javax.websocket.DecodeException;
  9. import javax.websocket.Decoder;
  10. import javax.websocket.EndpointConfig;
  11.  
  12. public class ChatMessageDecoder implements Decoder.Text {
  13.     @Override
  14.     public void init(final EndpointConfig config) {
  15.     }
  16.  
  17.     @Override
  18.     public void destroy() {
  19.     }
  20.  
  21.     @Override
  22.     public ChatMessage decode(final String textMessage) throws DecodeException {
  23.         ChatMessage chatMessage = new ChatMessage();
  24.         JsonObject obj = Json.createReader(new StringReader(textMessage))
  25.                 .readObject();
  26.         chatMessage.setMessage(obj.getString("message"));
  27.         chatMessage.setSender(obj.getString("sender"));
  28.         chatMessage.setReceived(new Date());
  29.         return chatMessage;
  30.     }
  31.  
  32.     @Override
  33.     public boolean willDecode(final String s) {
  34.         return true;
  35.     }
  36. }

同樣再看下編碼類的代碼,這個類相反,是將ChatMessage類轉(zhuǎn)換為Json格式,代碼如下:

 
 
 
 
  1. package com.hascode.tutorial;
  2.  
  3. import javax.json.Json;
  4. import javax.websocket.EncodeException;
  5. import javax.websocket.Encoder;
  6. import javax.websocket.EndpointConfig;
  7.  
  8. public class ChatMessageEncoder implements Encoder.Text {
  9.     @Override
  10.     public void init(final EndpointConfig config) {
  11.     }
  12.  
  13.     @Override
  14.     public void destroy() {
  15.     }
  16.  
  17.     @Override
  18.     public String encode(final ChatMessage chatMessage) throws EncodeException {
  19.         return Json.createObjectBuilder()
  20.                 .add("message", chatMessage.getMessage())
  21.                 .add("sender", chatMessage.getSender())
  22.                 .add("received", chatMessage.getReceived().toString()).build()
  23.                 .toString();
  24.     }
  25. }

這里可以看到JSR-353的強大威力,只需要調(diào)用Json.createObjectBuilder就可以輕易把一個DTO對象轉(zhuǎn)化為JSON了。

#p#

通過Bootstrap、Javacsript搭建簡易客戶端

最后,我們綜合運用著名的Bootstrap、jQuery框架和Javascript設(shè)計一個簡易的客戶端。我們在src/main/weapp目錄下新建立index.html文件,代碼如下:

 
 
 
 
  1. [..]
  2.  
  3.  
  4.     
  5.         
  6.             Chat sign in
  7.             Nickname 
  8.                 class="input-block-level" placeholder="Nickname" id="nickname">
  9.             
  10.                 Chatroom 
  11.                     id="chatroom">
  12.                     
  13.                     
  14.                     
  15.                     
  16.                 
  17.             
  •             
  •                 id="enterRoom">Sign in
  •         
  •     
  •     
  •  
  •     
  •         
  •             
  •             
  •             
  •                 Enter your message..
  •                 
  •                     
  •                     
  •                         value="Send message" />
  •                     Leave
  •                         room
  •                 
  •             
  •         
  •     
  • 在上面的代碼中,要注意如下幾點:

    在Javascript端要調(diào)用websocket的話,要用如下的方式發(fā)起連接即可:ws://IP:PORT/CONTEXT_PATH/ENDPOINT_URL e.g ws://0.0.0.0:8080/hascode/chat/java

    創(chuàng)建一個Websocket連接的方法很簡單,使用的是var wsocket = new WebSocket(‘ws://0.0.0.0:8080/hascode/chat/java’);

    要獲得來自服務(wù)端返回的信息,只需要在回調(diào)函數(shù)wsocket.onmessage中設(shè)置對應(yīng)的獲取返回信息的方法即可。

    發(fā)送一個Websocket消息到服務(wù)端,使用的方法是wsocket.send(),其中可以發(fā)送的消息可以文本或者二進制數(shù)據(jù)。

    關(guān)閉連接使用的是wsocket.close()。

    Websocket中還有其他很多種用法,具體的可以參考其標(biāo)準(zhǔn)規(guī)范文檔(http://tools.ietf.org/html/rfc6455)

    最后,我們通過

    mvn package embedded-glassfish:run

    進行代碼的部署,然后就可以看到本文開始部分截圖的效果。

    本文的代碼可以通過git獲得:

    git clone https://bitbucket.org/hascode/javaee7-websocket-chat.git

    讀者也可以通過這個地址下載可部署的war包:


    分享標(biāo)題:用JavaEE7、Websockets和GlassFish4打造聊天室(一)
    分享路徑:http://www.dlmjj.cn/article/dpehdgi.html