Skip to content

Commit d228d2a

Browse files
committed
Add SSE feature use
1 parent ab3eb9e commit d228d2a

File tree

6 files changed

+358
-25
lines changed

6 files changed

+358
-25
lines changed

README.md

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,67 @@
11
# Chat application
22

3-
Red5 WebSocket chat application example.
3+
Red5 chat application example.
44

5-
The example `index.html` defaults to using a WebSocket connection to localhost on port 5080.
5+
The example `index.html` defaults to using a WebSocket connection; SSE is also supported. Change the host and port entries to match your server as needed.
66

77
## Add the WebSocket filter servlet to webapps that require WebSocket support
88

99
```xml
10-
<filter>
11-
<filter-name>WebSocketFilter</filter-name>
12-
<filter-class>org.red5.net.websocket.server.WsFilter</filter-class>
13-
<async-supported>true</async-supported>
14-
</filter>
15-
<filter-mapping>
16-
<filter-name>WebSocketFilter</filter-name>
17-
<url-pattern>/*</url-pattern>
18-
<dispatcher>REQUEST</dispatcher>
19-
<dispatcher>FORWARD</dispatcher>
20-
</filter-mapping>
10+
<filter>
11+
<filter-name>WebSocketFilter</filter-name>
12+
<filter-class>org.red5.net.websocket.server.WsFilter</filter-class>
13+
<async-supported>true</async-supported>
14+
</filter>
15+
<filter-mapping>
16+
<filter-name>WebSocketFilter</filter-name>
17+
<url-pattern>/*</url-pattern>
18+
<dispatcher>REQUEST</dispatcher>
19+
<dispatcher>FORWARD</dispatcher>
20+
</filter-mapping>
2121
```
2222

23+
## Add the SSE servlet to webapps that require SSE support
24+
25+
```xml
26+
<servlet>
27+
<servlet-name>sse</servlet-name>
28+
<servlet-class>org.red5.server.net.sse.SSEServlet</servlet-class>
29+
<load-on-startup>-1</load-on-startup>
30+
<async-supported>true</async-supported>
31+
<!-- use CORS internally if no other CORS is enabled -->
32+
<init-param>
33+
<param-name>cors.enabled</param-name>
34+
<param-value>false</param-value>
35+
</init-param>
36+
</servlet>
37+
<servlet-mapping>
38+
<servlet-name>sse</servlet-name>
39+
<url-pattern>/events</url-pattern>
40+
<url-pattern>/events/*</url-pattern>
41+
</servlet-mapping>
42+
```
43+
44+
## Build and Deploy
45+
2346
Build the application from the command line with
2447

2548
```sh
2649
mvn package
2750
```
2851

52+
If you are using Red5 Pro, you will need to modify the WebSocket connection URL to include the appropriate capabilities parameter:
53+
54+
```javascript
55+
/*
56+
if we're hitting a red5pro server, ensure the port is 5080 and wsonly is true (for websocket only mode)
57+
?capabilities=1 : WebSocket Connection only
58+
?capabilities=3 : RTCConnection
59+
*/
60+
var socket = new WebSocket(protocol + '://' + window.location.hostname + ':' + port + '/chat/?capabilities=1', 'chat');
61+
// std red5
62+
//var socket = new WebSocket(protocol + '://' + window.location.hostname + ':' + port + '/chat', 'chat');
63+
```
64+
2965
Deploy your application by copying the war file into your `red5/webapps` directory. If the war file does not deploy withing a few minutes, this may indicate the war deployer bean is not created or running; a work-around is to expand the war contents into the webapps directory manually and restart Red5.
3066

3167
After deploy is complete, go to http://localhost:5080/chat/ in your browser (open two tabs if you want to chat back and forth on the same computer).
@@ -34,4 +70,4 @@ After deploy is complete, go to http://localhost:5080/chat/ in your browser (ope
3470

3571
You can find [compiled artifacts via Maven](http://mvnrepository.com/artifact/org.red5.demos/chat)
3672

37-
[Direct Download](https://github.com/Red5/red5-websocket-chat/releases/download/v2.0.19/chat-2.0.19.war)
73+
[Direct Download](https://oss.sonatype.org/content/repositories/releases/org/red5/demos/chat/2.0.23/chat-2.0.23.war)

pom.xml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<parent>
44
<groupId>org.red5</groupId>
55
<artifactId>red5-parent</artifactId>
6-
<version>2.0.19</version>
6+
<version>2.0.23</version>
77
</parent>
88
<modelVersion>4.0.0</modelVersion>
99
<groupId>org.red5.demos</groupId>
@@ -48,10 +48,10 @@
4848
<skipTests>true</skipTests>
4949
<!-- to be or not to be verbose -->
5050
<verbose>false</verbose>
51-
<maven.compiler.source>17</maven.compiler.source>
52-
<maven.compiler.target>17</maven.compiler.target>
53-
<java.release.level>17</java.release.level>
54-
<red5.version>2.0.19</red5.version>
51+
<maven.compiler.source>21</maven.compiler.source>
52+
<maven.compiler.target>21</maven.compiler.target>
53+
<java.release.level>21</java.release.level>
54+
<red5.version>2.0.23</red5.version>
5555
<gson.version>2.13.1</gson.version>
5656
</properties>
5757
<build>

src/main/java/org/red5/demos/chat/Router.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
import java.util.concurrent.ConcurrentHashMap;
44
import java.util.concurrent.ConcurrentMap;
5-
import java.util.concurrent.Future;
65
import java.util.concurrent.LinkedTransferQueue;
76

87
import org.red5.server.adapter.ApplicationLifecycle;
98
import org.red5.server.api.scope.IScope;
9+
import org.red5.server.net.sse.SSEService;
1010
import org.red5.server.util.ScopeUtils;
1111
import org.slf4j.Logger;
1212
import org.slf4j.LoggerFactory;
@@ -24,6 +24,8 @@ public class Router {
2424

2525
private WebSocketChatDataListener wsListener;
2626

27+
private SSEService sseService;
28+
2729
// messages are stored in a concurrent map to allow for thread-safe access
2830
// this is not strictly necessary for the router, but it can be useful if you want
2931
// entries are keyed by the path and the value is the message queue
@@ -70,6 +72,9 @@ public void route(IScope scope, String message) {
7072
if (wsListener != null) {
7173
wsListener.sendToAll(scope.getContextPath(), message);
7274
}
75+
if (sseService != null) {
76+
sseService.broadcastToScope(scope, message);
77+
}
7378
}
7479

7580
/**
@@ -98,7 +103,14 @@ private LinkedTransferQueue<String> getMessageQueue(String path) {
98103
public void setApp(Application app) {
99104
log.debug("Setting application: {}", app);
100105
this.app = app;
101-
final String contextPath = app.getScope().getContextPath();
106+
final IScope appScope = app.getScope();
107+
sseService = (SSEService) appScope.getServiceHandler(SSEService.BEAN_NAME);
108+
if (sseService == null) {
109+
log.warn("SSE service was null, SSE will not be available");
110+
} else {
111+
log.info("SSE service found in application scope: {}", appScope.getName());
112+
}
113+
final String contextPath = appScope.getContextPath();
102114
this.app.addListener(new ApplicationLifecycle() {
103115

104116
@Override
@@ -137,6 +149,9 @@ public void appStop(IScope scope) {
137149
if (wsListener != null) {
138150
wsListener.sendToAll(contextPath, message);
139151
}
152+
if (sseService != null) {
153+
sseService.broadcastToScope(appScope, message);
154+
}
140155
}
141156
} catch (InterruptedException e) {
142157
Thread.currentThread().interrupt();

src/main/webapp/WEB-INF/web.xml

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<?xml version="1.0" encoding="ISO-8859-1"?>
2-
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
3-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
2+
<web-app version="3.0"
3+
xmlns="http://java.sun.com/xml/ns/javaee"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
56
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
67
<display-name>chat</display-name>
78
<context-param>
@@ -12,12 +13,29 @@
1213
<filter>
1314
<filter-name>WebSocketFilter</filter-name>
1415
<filter-class>org.red5.net.websocket.server.WsFilter</filter-class>
15-
<async-supported>false</async-supported>
16+
<async-supported>true</async-supported>
1617
</filter>
1718
<filter-mapping>
1819
<filter-name>WebSocketFilter</filter-name>
1920
<url-pattern>/*</url-pattern>
2021
<dispatcher>REQUEST</dispatcher>
2122
<dispatcher>FORWARD</dispatcher>
2223
</filter-mapping>
24+
<!-- Server-Sent Events Servlet -->
25+
<servlet>
26+
<servlet-name>sse</servlet-name>
27+
<servlet-class>org.red5.server.net.sse.SSEServlet</servlet-class>
28+
<load-on-startup>-1</load-on-startup>
29+
<async-supported>true</async-supported>
30+
<!-- use CORS internally if no other CORS is enabled -->
31+
<init-param>
32+
<param-name>cors.enabled</param-name>
33+
<param-value>false</param-value>
34+
</init-param>
35+
</servlet>
36+
<servlet-mapping>
37+
<servlet-name>sse</servlet-name>
38+
<url-pattern>/events</url-pattern>
39+
<url-pattern>/events/*</url-pattern>
40+
</servlet-mapping>
2341
</web-app>

src/main/webapp/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<!doctype html>
22
<html>
33
<head>
4+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
45
<title>Red5 WebSocket Chat</title>
56
<style>
67
* { margin: 0; padding: 0; box-sizing: border-box; }

0 commit comments

Comments
 (0)