java-ee
WebSockets API
खोज…
टिप्पणियों
WebSocket एक प्रोटोकॉल है जो क्लाइंट और सर्वर / एंडपॉइंट के बीच एकल टीसीपी कनेक्शन का उपयोग करके संचार के लिए अनुमति देता है।
WebSocket को वेब ब्राउज़र और वेब सर्वर में लागू करने के लिए डिज़ाइन किया गया है, लेकिन इसका उपयोग किसी भी क्लाइंट या सर्वर एप्लिकेशन द्वारा किया जा सकता है।
वेबस्कैट के लिए जावा एपीआई के बारे में यह विषय जिसे JSR 356 द्वारा विकसित किया गया था और जावा EE 7 विनिर्देशों में शामिल किया गया था।
एक WebSocket संचार बनाना
WebSocket एकल टीसीपी कनेक्शन पर एक द्वैध / द्विदिश संचार प्रोटोकॉल प्रदान करता है।
- क्लाइंट एक सर्वर से एक कनेक्शन खोलता है जो एक WebSocket अनुरोध के लिए सुन रहा है
- क्लाइंट URI का उपयोग करके सर्वर से जुड़ता है।
- एक सर्वर कई ग्राहकों के अनुरोधों को सुन सकता है।
सर्वर समापन बिंदु
तुम बस व्याख्या के साथ एक POJO द्वारा एक WebSocket सर्वर entpoint बना सकते हैं @ServerEndpoint
। @OnMessage
एक विधि को सजाता है जो आने वाले संदेशों को प्राप्त करता है। जब किसी सहकर्मी से नया कनेक्शन प्राप्त होता है, तो उसे कॉल करने के लिए एक विधि को सजाने के लिए @OnOpen
का उपयोग किया जा सकता है। इसी तरह, एक कनेक्शन बंद होने पर @OnClose
साथ एनोटेट की गई विधि को कहा जाता है।
@ServerEndpoint("/websocket")
public class WebSocketServerEndpoint
{
@OnOpen
public void open(Session session) {
System.out.println("a client connected");
}
@OnClose
public void close(Session session) {
System.out.println("a client disconnected");
}
@OnMessage
public void handleMessage(String message) {
System.out.println("received a message from a websocket client! " + message);
}
}
क्लाइंट एनपॉइंट
सर्वर के लिए इसी प्रकार आप व्याख्या के साथ एक POJO द्वारा एक WebSocket ग्राहक अंत बिंदु बना सकते हैं endpoint @ClientEndpoint
।
@ClientEndpoint
public class WebsocketClientEndpoint {
Session userSession = null;
// in our case i.e. "ws://localhost:8080/myApp/websocket"
public WebsocketClientEndpoint(URI endpointURI) {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.connectToServer(this, endpointURI);
}
@OnOpen
public void onOpen(Session userSession) {
System.out.println("opening websocket");
this.userSession = userSession;
}
@OnClose
public void onClose(Session userSession, CloseReason reason) {
System.out.println("closing websocket");
this.userSession = null;
}
@OnMessage
public void onMessage(String message) {
System.out.println("received message: "+ message);
}
public void sendMessage(String message) {
System.out.println("sending message: "+ message);
this.userSession.getAsyncRemote().sendText(message);
}
}
एनकोडर और डिकोडर: ऑब्जेक्ट-ओरिएंटेड वेब पॉकेट्स
एनकोडर और डिकोडर्स के लिए धन्यवाद, जेएसआर 356 एक वस्तु उन्मुख संचार मॉडल प्रदान करता है।
संदेश की परिभाषा
मान लें कि सभी प्राप्त संदेशों को सभी जुड़े सत्रों में वापस भेजे जाने से पहले सर्वर द्वारा रूपांतरित किया जाना है:
public abstract class AbstractMsg {
public abstract void transform();
}
अब मान लेते हैं कि सर्वर दो संदेश प्रकारों का प्रबंधन करता है: एक पाठ-आधारित संदेश और पूर्णांक-आधारित संदेश।
पूर्णांक संदेश सामग्री को स्वयं से गुणा करते हैं।
public class IntegerMsg extends AbstractMsg {
private Integer content;
public IntegerMsg(int content) {
this.content = content;
}
public Integer getContent() {
return content;
}
public void setContent(Integer content) {
this.content = content;
}
@Override
public void transform() {
this.content = this.content * this.content;
}
}
स्ट्रिंग संदेश कुछ पाठ प्रस्तुत करता है:
public class StringMsg extends AbstractMsg {
private String content;
public StringMsg(String content) {
this.content = content;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public void transform() {
this.content = "Someone said: " + this.content;
}
}
एनकोडर और डिकोडर
प्रत्येक संदेश के लिए एक एनकोडर है और सभी संदेशों के लिए एक एकल डिकोडर है। Encoder.XXX<Type>
को लागू करना होगा। Encoder.XXX<Type>
इंटरफ़ेस जब डिकोडर को डिकोडर को लागू करना होगा। Decoder.XXX<Type>
।
एन्कोडिंग काफी सीधा है: एक संदेश से, encode
में encode
विधि एक JSON स्वरूपित स्ट्रिंग का उत्पादन करना चाहिए। यहाँ IntegerMsg
लिए उदाहरण IntegerMsg
।
public class IntegerMsgEncoder implements Encoder.Text<IntegerMsg> {
@Override
public String encode(IntegerMsg object) throws EncodeException {
JsonObjectBuilder builder = Json.createObjectBuilder();
builder.add("content", object.getContent());
JsonObject jsonObject = builder.build();
return jsonObject.toString();
}
@Override
public void init(EndpointConfig config) {
System.out.println("IntegerMsgEncoder initializing");
}
@Override
public void destroy() {
System.out.println("IntegerMsgEncoder closing");
}
}
StringMsg
वर्ग के लिए समान एन्कोडिंग। जाहिर है, एनकोडर को अमूर्त वर्गों के माध्यम से कारक बनाया जा सकता है।
public class StringMsgEncoder implements Encoder.Text<StringMsg> {
@Override
public String encode(StringMsg object) throws EncodeException {
JsonObjectBuilder builder = Json.createObjectBuilder();
builder.add("content", object.getContent());
JsonObject jsonObject = builder.build();
return jsonObject.toString();
}
@Override
public void init(EndpointConfig config) {
System.out.println("StringMsgEncoder initializing");
}
@Override
public void destroy() {
System.out.println("StringMsgEncoder closing");
}
}
डिकोडर दो चरणों में आगे बढ़ता है: अगर प्राप्त संदेश को willDecode
साथ willDecode
स्वरूप में फिट किया जाता है, तो willDecode
और प्राप्त कच्चे संदेश को decode
साथ ऑब्जेक्ट में बदलना:
सार्वजनिक वर्ग MsgDecoder डिकोडर लागू करता है। पाठ {
@Override
public AbstractMsg decode(String s) throws DecodeException {
// Thanks to willDecode(s), one knows that
// s is a valid JSON and has the attribute
// "content"
JsonObject json = Json.createReader(new StringReader(s)).readObject();
JsonValue contentValue = json.get("content");
// to know if it is a IntegerMsg or a StringMsg,
// contentValue type has to be checked:
switch (contentValue.getValueType()) {
case STRING:
String stringContent = json.getString("content");
return new StringMsg(stringContent);
case NUMBER:
Integer intContent = json.getInt("content");
return new IntegerMsg(intContent);
default:
return null;
}
}
@Override
public boolean willDecode(String s) {
// 1) Incoming message is a valid JSON object
JsonObject json;
try {
json = Json.createReader(new StringReader(s)).readObject();
}
catch (JsonParsingException e) {
// ...manage exception...
return false;
}
catch (JsonException e) {
// ...manage exception...
return false;
}
// 2) Incoming message has required attributes
boolean hasContent = json.containsKey("content");
// ... proceed to additional test ...
return hasContent;
}
@Override
public void init(EndpointConfig config) {
System.out.println("Decoding incoming message...");
}
@Override
public void destroy() {
System.out.println("Incoming message decoding finished");
}
}
ServerEndPoint
सर्वर एंडप्वाइंट सुंदर तीन मुख्य अंतरों के साथ वेबसॉकेट संचार की तरह दिखता है:
ServerEndPoint एनोटेशन है
encoders
औरdecoders
गुणसंदेश
sendText
साथ नहीं बल्किsendText
साथ भेजेsendObject
ऑनर्रोट एनोटेशन का उपयोग किया जाता है। यदि
willDecode
दौरान कोई त्रुटि हुईwillDecode
, तो इसे यहां संसाधित किया जाएगा और त्रुटि की जानकारी क्लाइंट को वापस भेज दी जाएगी@ServerEndpoint (मान = "/ webSocketObjectEndPoint", डिकोडर्स = {MsgDecoder.class}, एनकोडर्स = {StringMsgEncoder.class, IntegerMsgEncoder.class}) सार्वजनिक वर्ग ServerEndPoint {}
@OnOpen public void onOpen(Session session) { System.out.println("A session has joined"); } @OnClose public void onClose(Session session) { System.out.println("A session has left"); } @OnMessage public void onMessage(Session session, AbstractMsg message) { if (message instanceof IntegerMsg) { System.out.println("IntegerMsg received!"); } else if (message instanceof StringMsg) { System.out.println("StringMsg received!"); } message.transform(); sendMessageToAllParties(session, message); } @OnError public void onError(Session session, Throwable throwable) { session.getAsyncRemote().sendText(throwable.getLocalizedMessage()); } private void sendMessageToAllParties(Session session, AbstractMsg message) { session.getOpenSessions().forEach(s -> { s.getAsyncRemote().sendObject(message); }); }
}
जैसा कि मैं काफी क्रियाशील था, यहाँ उन लोगों के लिए एक बुनियादी जावास्क्रिप्ट क्लाइंट है जो एक दृश्य उदाहरण चाहते हैं। कृपया ध्यान दें कि यह एक चैट जैसा उदाहरण है: सभी जुड़े हुए पक्षों को जवाब मिलेगा।
<!DOCTYPE html>
<html>
<head>
<title>Websocket-object</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- start of BAD PRACTICE! all style and script must go into a
dedicated CSS / JavaScript file-->
<style>
body{
background: dimgray;
}
.container{
width: 100%;
display: flex;
}
.left-side{
width: 30%;
padding: 2%;
box-sizing: border-box;
margin: auto;
margin-top: 0;
background: antiquewhite;
}
.left-side table{
width: 100%;
border: 1px solid black;
margin: 5px;
}
.left-side table td{
padding: 2px;
width: 50%;
}
.left-side table input{
width: 100%;
box-sizing: border-box;
}
.right-side{
width: 70%;
background: floralwhite;
}
</style>
<script>
var ws = null;
window.onload = function () {
// replace the 'websocket-object' with the
// context root of your web application.
ws = new WebSocket("ws://localhost:8080/websocket-object/webSocketObjectEndPoint");
ws.onopen = onOpen;
ws.onclose = onClose;
ws.onmessage = onMessage;
};
function onOpen() {
printText("", "connected to server");
}
function onClose() {
printText("", "disconnected from server");
}
function onMessage(event) {
var msg = JSON.parse(event.data);
printText("server", JSON.stringify(msg.content));
}
function sendNumberMessage() {
var content = new Number(document.getElementById("inputNumber").value);
var json = {content: content};
ws.send(JSON.stringify(json));
printText("client", JSON.stringify(json));
}
function sendTextMessage() {
var content = document.getElementById("inputText").value;
var json = {content: content};
ws.send(JSON.stringify(json));
printText("client", JSON.stringify(json));
}
function printText(sender, text) {
var table = document.getElementById("outputTable");
var row = table.insertRow(1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
switch (sender) {
case "client":
row.style.color = "orange";
break;
case "server":
row.style.color = "green";
break;
default:
row.style.color = "powderblue";
}
cell1.innerHTML = new Date().toISOString();
cell2.innerHTML = sender;
cell3.innerHTML = text;
}
</script>
<!-- end of bad practice -->
</head>
<body>
<div class="container">
<div class="left-side">
<table>
<tr>
<td>Enter a text</td>
<td><input id="inputText" type="text" /></td>
</tr>
<tr>
<td>Send as text</td>
<td><input type="submit" value="Send" onclick="sendTextMessage();"/></td>
</tr>
</table>
<table>
<tr>
<td>Enter a number</td>
<td><input id="inputNumber" type="number" /></td>
</tr>
<tr>
<td>Send as number</td>
<td><input type="submit" value="Send" onclick="sendNumberMessage();"/></td>
</tr>
</table>
</div>
<div class="right-side">
<table id="outputTable">
<tr>
<th>Date</th>
<th>Sender</th>
<th>Message</th>
</tr>
</table>
</div>
</div>
</body>
</html>
कोड पूरा हो गया है और Payara 4.1 के तहत परीक्षण किया गया था। उदाहरण शुद्ध मानक है (कोई बाहरी पुस्तकालय / ढांचा नहीं)