-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit bcaa978
Showing
56 changed files
with
44,201 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
## webrtc-cli test | ||
1. run signal | ||
2. run webrtc-cli, type signal server address and select a folder, click "connect", then get token | ||
3. deploy simple-test-page, the easiest way is using [Web Server for Chrome](https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?utm_source=chrome-app-launcher-info-dialog) | ||
4. open index.html, type token, select "offer", click "connect" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-parent</artifactId> | ||
<version>2.2.3.RELEASE</version> | ||
<relativePath/> <!-- lookup parent from repository --> | ||
</parent> | ||
<groupId>me.rtmsoft.webrtc</groupId> | ||
<artifactId>signal</artifactId> | ||
<version>0.0.1-SNAPSHOT</version> | ||
<name>signal</name> | ||
<description>webrtc signal server</description> | ||
|
||
<properties> | ||
<java.version>1.8</java.version> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-web</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-websocket</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-test</artifactId> | ||
<scope>test</scope> | ||
<exclusions> | ||
<exclusion> | ||
<groupId>org.junit.vintage</groupId> | ||
<artifactId>junit-vintage-engine</artifactId> | ||
</exclusion> | ||
</exclusions> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-maven-plugin</artifactId> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
</project> |
42 changes: 42 additions & 0 deletions
42
signal/src/main/java/me/rtmsoft/webrtc/signal/CustomSubProtocolWebSocketHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package me.rtmsoft.webrtc.signal; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.messaging.MessageChannel; | ||
import org.springframework.messaging.SubscribableChannel; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.socket.CloseStatus; | ||
import org.springframework.web.socket.WebSocketSession; | ||
import org.springframework.web.socket.messaging.SubProtocolWebSocketHandler; | ||
|
||
public class CustomSubProtocolWebSocketHandler extends SubProtocolWebSocketHandler { | ||
private static final Logger LOGGER = LoggerFactory.getLogger(CustomSubProtocolWebSocketHandler.class); | ||
|
||
private SessionManager sessionManager; | ||
private PeerManager peerManager; | ||
|
||
public CustomSubProtocolWebSocketHandler( | ||
MessageChannel clientInboundChannel, | ||
SubscribableChannel clientOutboundChannel, | ||
SessionManager sessionManager, | ||
PeerManager peerManager) { | ||
super(clientInboundChannel, clientOutboundChannel); | ||
this.sessionManager = sessionManager; | ||
this.peerManager = peerManager; | ||
} | ||
|
||
@Override | ||
public void afterConnectionEstablished(WebSocketSession session) throws Exception { | ||
LOGGER.info(session.getId() + " connection established"); | ||
sessionManager.add(session); | ||
super.afterConnectionEstablished(session); | ||
} | ||
|
||
@Override | ||
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { | ||
LOGGER.info(session.getId() + " connection closed"); | ||
sessionManager.remove(session); | ||
peerManager.remove(session.getId()); | ||
super.afterConnectionClosed(session, closeStatus); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package me.rtmsoft.webrtc.signal; | ||
|
||
public class DTO{ | ||
|
||
private String remote; | ||
private String value; | ||
|
||
public DTO() { | ||
} | ||
|
||
public DTO(String remote, String value) { | ||
this.remote = remote; | ||
this.value = value; | ||
} | ||
|
||
public void setRemote(String remote) { | ||
this.remote = remote; | ||
} | ||
|
||
public void setValue(String value) { | ||
this.value = value; | ||
} | ||
|
||
public String getRemote() { | ||
return remote; | ||
} | ||
|
||
public String getValue() { | ||
return value; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "DTO{" + | ||
"remote='" + remote + '\'' + | ||
", value='" + value + '\'' + | ||
'}'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package me.rtmsoft.webrtc.signal; | ||
|
||
import java.security.Principal; | ||
|
||
public class Peer implements Principal { | ||
|
||
public static final String OFFER_SUFFIX = "_offer"; | ||
public static final String ANSWER_SUFFIX = "_answer"; | ||
|
||
private final String token; | ||
|
||
private final String type; | ||
|
||
private final String sessionId; | ||
|
||
@Override | ||
public String toString() { | ||
return "Peer{" + | ||
"token='" + token + '\'' + | ||
", type='" + type + '\'' + | ||
", sessionId='" + sessionId + '\'' + | ||
'}'; | ||
} | ||
|
||
public Peer(String token, String type, String sessionId) { | ||
this.token = token; | ||
this.type = type; | ||
this.sessionId = sessionId; | ||
} | ||
|
||
public String getToken() { | ||
return token; | ||
} | ||
|
||
public String getType() { | ||
return type; | ||
} | ||
|
||
public String getSessionId() { | ||
return sessionId; | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
if ("answer".equals(type)) { | ||
return token + "_" + type; | ||
}else{ | ||
return token + "_" + type + "_" + sessionId; | ||
} | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
signal/src/main/java/me/rtmsoft/webrtc/signal/PeerManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package me.rtmsoft.webrtc.signal; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.Map; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
@Service | ||
public class PeerManager { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(PeerManager.class); | ||
|
||
private Map<String, Peer> peerMap = new ConcurrentHashMap<>(); | ||
|
||
public boolean isRegistered(String name) { | ||
return peerMap.get(name) != null; | ||
} | ||
|
||
public void add(Peer peer) { | ||
peerMap.put(peer.getName(), peer); | ||
} | ||
|
||
public Peer pair(Peer peer, String remote) { | ||
if ("offer".equals(peer.getType())) { | ||
return peerMap.get(peer.getToken() + Peer.ANSWER_SUFFIX); | ||
}else if ("answer".equals(peer.getType())){ | ||
return peerMap.get(peer.getToken() + Peer.OFFER_SUFFIX + "_" + remote); | ||
} | ||
return null; | ||
} | ||
|
||
public void remove(String sessionId) { | ||
peerMap.forEach((k, v) -> { | ||
if (v.getSessionId().equals(sessionId)){ | ||
peerMap.remove(k); | ||
LOGGER.info(sessionId + " remove peer " + v.getName()); | ||
} | ||
}); | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
signal/src/main/java/me/rtmsoft/webrtc/signal/PrincipalChannelInterceptor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package me.rtmsoft.webrtc.signal; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.messaging.Message; | ||
import org.springframework.messaging.MessageChannel; | ||
import org.springframework.messaging.simp.stomp.StompCommand; | ||
import org.springframework.messaging.simp.stomp.StompHeaderAccessor; | ||
import org.springframework.messaging.support.ChannelInterceptor; | ||
import org.springframework.messaging.support.MessageHeaderAccessor; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.util.StringUtils; | ||
import org.springframework.web.socket.CloseStatus; | ||
|
||
@Component | ||
public class PrincipalChannelInterceptor implements ChannelInterceptor { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(PrincipalChannelInterceptor.class); | ||
|
||
@Autowired | ||
private PeerManager peerManager; | ||
|
||
@Autowired | ||
private SessionManager sessionManager; | ||
|
||
@Override | ||
public Message<?> preSend(Message<?> message, MessageChannel channel) { | ||
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class); | ||
if (accessor != null && accessor.getCommand() == StompCommand.CONNECT) { | ||
String sessionId = accessor.getSessionId(); | ||
try { | ||
String token = accessor.getNativeHeader("token").get(0); | ||
String type = accessor.getNativeHeader("type").get(0); | ||
if (("offer".equals(type) || "answer".equals(type)) && !StringUtils.isEmpty(token)) { | ||
if (!peerManager.isRegistered(token)) { | ||
Peer peer = new Peer(token, type, sessionId); | ||
peerManager.add(peer); | ||
accessor.setUser(peer); | ||
LOGGER.info(sessionId + " set principal " + peer.getName()); | ||
}else{ | ||
sessionManager.close(sessionId, CloseStatus.SERVICE_RESTARTED); | ||
} | ||
}else { | ||
sessionManager.close(sessionId, CloseStatus.PROTOCOL_ERROR); | ||
} | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
sessionManager.close(sessionId, CloseStatus.PROTOCOL_ERROR); | ||
} | ||
} | ||
return message; | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
signal/src/main/java/me/rtmsoft/webrtc/signal/SessionManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package me.rtmsoft.webrtc.signal; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.web.socket.CloseStatus; | ||
import org.springframework.web.socket.WebSocketSession; | ||
|
||
import java.io.IOException; | ||
import java.util.Map; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
@Service | ||
public class SessionManager { | ||
|
||
private Map<String, WebSocketSession> sessionMap = new ConcurrentHashMap<>(); | ||
|
||
public void add(WebSocketSession session) { | ||
sessionMap.put(session.getId(), session); | ||
} | ||
|
||
public void remove(WebSocketSession session) { | ||
sessionMap.remove(session.getId()); | ||
} | ||
|
||
public WebSocketSession get(String sessionId) { | ||
return sessionMap.get(sessionId); | ||
} | ||
|
||
public void close(String sessionId, CloseStatus status) { | ||
WebSocketSession session = get(sessionId); | ||
if (session != null) { | ||
try { | ||
session.close(status); | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
signal/src/main/java/me/rtmsoft/webrtc/signal/SignalApplication.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package me.rtmsoft.webrtc.signal; | ||
|
||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
|
||
@SpringBootApplication | ||
public class SignalApplication { | ||
|
||
public static void main(String[] args) { | ||
SpringApplication.run(SignalApplication.class, args); | ||
} | ||
|
||
} |
45 changes: 45 additions & 0 deletions
45
signal/src/main/java/me/rtmsoft/webrtc/signal/SignalController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package me.rtmsoft.webrtc.signal; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.messaging.handler.annotation.MessageMapping; | ||
import org.springframework.messaging.handler.annotation.Payload; | ||
import org.springframework.messaging.simp.SimpMessagingTemplate; | ||
import org.springframework.stereotype.Controller; | ||
|
||
import java.security.Principal; | ||
|
||
@Controller | ||
public class SignalController { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(SignalController.class); | ||
|
||
@Autowired | ||
private PeerManager peerManager; | ||
|
||
@Autowired | ||
private SimpMessagingTemplate messagingTemplate; | ||
|
||
@MessageMapping("/sdp") | ||
public void sdp(@Payload DTO data, Principal principal) { | ||
Peer peer = (Peer) principal; | ||
Peer pair = peerManager.pair(peer, data.getRemote()); | ||
LOGGER.info("pair:" + peer + ", " + pair); | ||
if(pair != null) { | ||
DTO dto = new DTO(peer.getSessionId(), data.getValue()); | ||
messagingTemplate.convertAndSendToUser(pair.getName(), "/queue/onsdp", dto); | ||
} | ||
} | ||
|
||
@MessageMapping("/candidate") | ||
public void candidate(@Payload DTO data, Principal principal) { | ||
Peer peer = (Peer) principal; | ||
Peer pair = peerManager.pair(peer, data.getRemote()); | ||
LOGGER.info("pair:" + peer + ", " + pair); | ||
if(pair != null) { | ||
DTO dto = new DTO(peer.getSessionId(), data.getValue()); | ||
messagingTemplate.convertAndSendToUser(pair.getName(), "/queue/oncandidate", dto); | ||
} | ||
} | ||
} |
Oops, something went wrong.