-
Notifications
You must be signed in to change notification settings - Fork 1
/
getting-started.html
212 lines (199 loc) · 16.9 KB
/
getting-started.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Chapter 1. Getting Started</title><link rel="stylesheet" type="text/css" href="/tyrus-project.github.io/documentation.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="Tyrus 2.0.5 User Guide"><link rel="up" href="index.html" title="Tyrus 2.0.5 User Guide"><link rel="prev" href="preface.html" title="Preface"><link rel="next" href="modules-and-dependencies.html" title="Chapter 2. Tyrus Modules and Dependencies"></head><body class="contents"><div class="contents" bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 1. Getting Started</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="preface.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="modules-and-dependencies.html">Next</a></td></tr></table><hr></div><div lang="en" class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="getting-started"></a>Chapter 1. Getting Started</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="getting-started.html#getting-started-wsapi-artifact">1.1. WebSocket Services Using Java API for WebSocket</a></span></dt><dd><dl><dt><span class="section"><a href="getting-started.html#d0e35">1.1.1. Creating Annotated Server Endpoint</a></span></dt><dt><span class="section"><a href="getting-started.html#d0e79">1.1.2. Client Endpoint</a></span></dt><dt><span class="section"><a href="getting-started.html#websocket-programmatic-endpoint">1.1.3. Creating Server Endpoint Programmatically</a></span></dt><dt><span class="section"><a href="getting-started.html#standalone-mode">1.1.4. Tyrus in Standalone Mode</a></span></dt></dl></dd></dl></div><p>
This chapter provides a quick introduction on how to get started building
WebSocket services using Java API for WebSocket and Tyrus. The example described here presents how to implement
simple websocket service as JavaEE web application that can be deployed on any servlet container
supporting Servlet 3.1 and higher. It also discusses starting Tyrus in standalone mode.
</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="getting-started-wsapi-artifact"></a>1.1. WebSocket Services Using Java API for WebSocket</h2></div></div></div><p>
First, to use the Java API for WebSocket in your project you need to depend on the following artifact:
</p><pre class="
 toolbar: false;
 brush: xml;
 gutter: false;"><dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-api</artifactId>
<version>2.0.0</version>
</dependency>
</pre><p>
</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="d0e35"></a>1.1.1. Creating Annotated Server Endpoint</h3></div></div></div><p>
In this section we will create a simple server side websocket endpoint which will echo the received
message back to the sender. We will deploy this endpoint on the container.
</p><p>
In Java API for WebSocket and Tyrus, there are two basic approaches how to create an endpoint - either annotated endpoint,
or programmatic endpoint.
By annotated endpoint we mean endpoint constructed by using annotations (<code class="code">jakarta.websocket.server.ServerEndpoint</code>
for server endpoint and <code class="code">jakarta.websocket.ClientEndpoint</code> for client endpoint), like in
<a class="link" href="getting-started.html#websocket-annotated-echo-endpoint" title="Example 1.1. Annotated Echo Endpoint">"Annotated Echo Endpoint"</a>.
</p><div class="example"><a name="websocket-annotated-echo-endpoint"></a><p class="title"><b>Example 1.1. Annotated Echo Endpoint</b></p><div class="example-contents"><pre class="
 toolbar: false;
 brush: java;
 ">@ServerEndpoint(value = "/echo")
public class EchoEndpointAnnotated {
@OnMessage
public String onMessage(String message, Session session) {
return message;
}
}
</pre></div></div><p><br class="example-break">
</p><p>
The functionality of the <code class="code">EchoEndpointAnnotated</code> is fairly simple - to send the received message
back to the sender. To turn a POJO (Plain Old Java Object) to WebSocket server endpoint, the annotation
<code class="code">@ServerEndpoint(value = "/echo")</code> needs to be put on the POJO - see line 1. The URI path of the endpoint
is <code class="code">"/echo"</code>. The annotation <code class="code">@OnMessage</code> - line 3 on the method <code class="code">public String
onMessage(String message, Session session)</code> indicates that this method
will be called whenever text message is received. On line 5 in this method the message is sent back to
the user by returning it from the message.
</p><p>
The application containing only the <code class="code">EchoEndpointAnnotated</code> class can be deployed to the container.
</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="d0e79"></a>1.1.2. Client Endpoint</h3></div></div></div><p>
Let's create the client part of the application. The client part may be written in JavaScript or any
other technology supporting WebSockets. We will use Java API for WebSocket and Tyrus to demonstrate how to develop
programmatic client endpoint.
The following code is used as a client part to communicate with the <code class="code">EchoEndpoint</code> deployed on server
using Tyrus and Java API for WebSocket.
</p><p>
The example <a class="link" href="getting-started.html#websocket-client-endpoint" title="Example 1.2. Client Endpoint">"Client Endpoint"</a> utilizes the concept
of the programmatic endpoint. By programmatic endpoint we mean endpoint which is created by extending
class <code class="code">jakarta.websocket.Endpoint</code>.
The example is standalone java application which needs to depend on some Tyrus artifacts to work
correctly, see <a class="link" href="getting-started.html#standalone-mode" title="1.1.4. Tyrus in Standalone Mode">"Tyrus Standalone Mode"</a>.
In the example first the <code class="code">CountDownLatch</code> is initialized. It is needed as a bocking data
structure - on line 31 it either waits for 100 seconds, or until it gets counted down (line 22).
On line 9 the <code class="code">jakarta.websocket.ClientEndpointConfig</code> is created - we will need it later
to connect the endpoint to the server. On line 11 the <code class="code">org.glassfish.tyrus.client.ClientManager</code>
is created. it implements the <code class="code">jakarta.websocket.WebSocketContainer</code> and is used to connect
to server. This happens on next line. The client endpoint functionality is contained in the <code class="code">
jakarta.websocket.Endpoint</code> lazy instantiation. In the <code class="code">onOpen</code> method new MessageHandler
is registered (the received message is just printed on the console and the latch is counted down). After
the registration the message is sent to the server (line 25).
</p><div class="example"><a name="websocket-client-endpoint"></a><p class="title"><b>Example 1.2. Client Endpoint</b></p><div class="example-contents"><pre class="
 toolbar: false;
 brush: java;
 ">public class DocClient {
private static CountDownLatch messageLatch;
private static final String SENT_MESSAGE = "Hello World";
public static void main(String [] args){
try {
messageLatch = new CountDownLatch(1);
final ClientEndpointConfig cec = ClientEndpointConfig.Builder.create().build();
ClientManager client = ClientManager.createClient();
client.connectToServer(new Endpoint() {
@Override
public void onOpen(Session session, EndpointConfig config) {
try {
session.addMessageHandler(new MessageHandler.Whole<String>() {
@Override
public void onMessage(String message) {
System.out.println("Received message: "+message);
messageLatch.countDown();
}
});
session.getBasicRemote().sendText(SENT_MESSAGE);
} catch (IOException e) {
e.printStackTrace();
}
}
}, cec, new URI("ws://localhost:8025/websockets/echo"));
messageLatch.await(100, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
}
}
}</pre></div></div><p><br class="example-break">
</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="websocket-programmatic-endpoint"></a>1.1.3. Creating Server Endpoint Programmatically</h3></div></div></div><p>
Similarly to <a class="link" href="getting-started.html#websocket-client-endpoint" title="Example 1.2. Client Endpoint">"Client Endpoint"</a> the server registered endpoint
may also be the programmatic one:
</p><div class="example"><a name="websocket-programmatic-echo-endpoint"></a><p class="title"><b>Example 1.3. Programmatic Echo Endpoint</b></p><div class="example-contents"><pre class="
 toolbar: false;
 brush: java;
 ">public class EchoEndpointProgrammatic extends Endpoint {
@Override
public void onOpen(final Session session, EndpointConfig config) {
session.addMessageHandler(new MessageHandler.Whole<String>() {
@Override
public void onMessage(String message) {
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}</pre></div></div><p><br class="example-break">
</p><p>
The functionality of the <code class="code">EchoEndpointProgrammatic</code> is fairly simple - to send the received message back to the sender.
The programmatic server endpoint needs to extend <code class="code">jakarta.websocket.Endpoint</code> - line 1.
Mehod <code class="code">public void onOpen(final Session session, EndpointConfig config)</code> gets called once new
connection to this endpoin0t is opened. In this method the <code class="code">MessageHandler</code> is registered to the
<code class="code">jakarta.websocket.Session</code> instance, which opened the connection. Method <code class="code">public void
onMessage(String message)</code> gets called once the message is received. On line 8 the message
is sent back to the sender.
</p></div><p>
To see how both annotated and programmatic endpoints may be deployed please check the section Deployment.
In short: you need to put the server endpoint classes into WAR, deploy on server and the endpoints will
be scanned by server and deployed.
</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="standalone-mode"></a>1.1.4. Tyrus in Standalone Mode</h3></div></div></div><p>
</p><p>
To use Tyrus in standalone mode it is necessary to depend on correct Tyrus artifacts.
The following artifacts need to be added to your pom to use Tyrus:
</p><pre class="
 toolbar: false;
 brush: xml;
 gutter: false;"><dependency>
<groupId>org.glassfish.tyrus</groupId>
<artifactId>tyrus-server</artifactId>
<version>2.0.5</version>
</dependency>
<dependency>
<groupId>org.glassfish.tyrus</groupId>
<artifactId>tyrus-container-grizzly-server</artifactId>
<version>2.0.5</version>
</dependency></pre><p>
</p><p>
Let's use the very same example like for Java API for WebSocket and deploy the <code class="code">EchoEndpointAnnotated</code> on the
standalone Tyrus server on the hostname "localhost", port 8025 and path "/websockets", so the endpoint
will be available at address "ws://localhost:8025/websockets/echo".
</p><pre class="
 toolbar: false;
 brush: java;
 gutter: false;">public void runServer() {
Server server = new Server("localhost", 8025, "/websockets", null, EchoEndpoint.class);
try {
server.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Please press a key to stop the server.");
reader.readLine();
} catch (Exception e) {
e.printStackTrace();
} finally {
server.stop();
}
}</pre><p>
</p></div></div></div><link href="http://tyrus.java.net/sh/shCore.css" rel="stylesheet" type="text/css"><link href="http://tyrus.java.net/sh/shThemeDefault.css" rel="stylesheet" type="text/css"><script src="http://tyrus.java.net/sh/shCore.js" type="text/javascript"></script><script src="http://tyrus.java.net/sh/shAutoloader.js" type="text/javascript"></script><script type="text/javascript">
function path() {
var args = arguments,
result = []
;
for(var i = 0; i < args.length; i++)
result.push(args[i].replace('@', 'http://tyrus.java.net/sh/'));
return result
};
SyntaxHighlighter.autoloader.apply(null, path(
'applescript @shBrushAppleScript.js',
'actionscript3 as3 @shBrushAS3.js',
'bash shell @shBrushBash.js',
'coldfusion cf @shBrushColdFusion.js',
'cpp c @shBrushCpp.js',
'c# c-sharp csharp @shBrushCSharp.js',
'css @shBrushCss.js',
'delphi pascal @shBrushDelphi.js',
'diff patch pas @shBrushDiff.js',
'erl erlang @shBrushErlang.js',
'groovy @shBrushGroovy.js',
'java @shBrushJava.js',
'jfx javafx @shBrushJavaFX.js',
'js jscript javascript @shBrushJScript.js',
'perl pl @shBrushPerl.js',
'php @shBrushPhp.js',
'text plain @shBrushPlain.js',
'py python @shBrushPython.js',
'ruby rails ror rb @shBrushRuby.js',
'sass scss @shBrushSass.js',
'scala @shBrushScala.js',
'sql @shBrushSql.js',
'vb vbnet @shBrushVb.js',
'xml xhtml xslt html @shBrushXml.js'
));
SyntaxHighlighter.all();
</script><script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-41373632-1', 'java.net');
ga('send', 'pageview');
</script><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="preface.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="modules-and-dependencies.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Preface </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 2. Tyrus Modules and Dependencies</td></tr></table></div></div></body></html>