mirror of https://github.com/OpenVidu/openvidu.git
openvidu-server: participant location and platform properties
parent
0828bc6f12
commit
4e81e6b600
|
@ -37,6 +37,7 @@ public class ProtocolElements {
|
|||
public static final String JOINROOM_ROOM_PARAM = "session";
|
||||
public static final String JOINROOM_METADATA_PARAM = "metadata";
|
||||
public static final String JOINROOM_SECRET_PARAM = "secret";
|
||||
public static final String JOINROOM_PLATFORM_PARAM = "platform";
|
||||
public static final String JOINROOM_RECORDER_PARAM = "recorder";
|
||||
|
||||
public static final String JOINROOM_PEERID_PARAM = "id";
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
|
@ -280,6 +281,11 @@
|
|||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.maxmind.geoip2</groupId>
|
||||
<artifactId>geoip2</artifactId>
|
||||
<version>2.12.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Test dependencies -->
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ public class CDREvent implements Comparable<CDREvent> {
|
|||
private Long startTime;
|
||||
private Integer duration;
|
||||
private Participant participant;
|
||||
private String location;
|
||||
private String platform;
|
||||
private MediaOptions mediaOptions;
|
||||
private String receivingFrom;
|
||||
private String reason;
|
||||
|
@ -88,6 +90,8 @@ public class CDREvent implements Comparable<CDREvent> {
|
|||
public CDREvent(CDREventName eventName, Participant participant, String sessionId) {
|
||||
this(eventName, sessionId);
|
||||
this.participant = participant;
|
||||
this.location = participant.getLocation();
|
||||
this.platform = participant.getPlatform();
|
||||
this.startTime = this.timeStamp;
|
||||
}
|
||||
|
||||
|
@ -122,6 +126,12 @@ public class CDREvent implements Comparable<CDREvent> {
|
|||
if (this.participant != null) {
|
||||
json.addProperty("participantId", this.participant.getParticipantPublicId());
|
||||
}
|
||||
if (this.location != null) {
|
||||
json.addProperty("location", this.location);
|
||||
}
|
||||
if (this.platform != null) {
|
||||
json.addProperty("platform", this.platform);
|
||||
}
|
||||
if (this.mediaOptions != null) {
|
||||
json.addProperty("connection", this.receivingFrom != null ? "INBOUND" : "OUTBOUND");
|
||||
json.addProperty("audioEnabled", this.mediaOptions.hasAudio());
|
||||
|
|
|
@ -38,7 +38,7 @@ import io.openvidu.server.recording.Recording;
|
|||
*
|
||||
* - 'sessionCreated': {sessionId, timestamp}
|
||||
* - 'sessionDestroyed': {sessionId, timestamp, startTime, endTime, duration, reason}
|
||||
* - 'participantJoined': {sessionId, timestamp, participantId}
|
||||
* - 'participantJoined': {sessionId, timestamp, participantId, location, platform}
|
||||
* - 'participantLeft': {sessionId, timestamp, participantId, startTime, endTime, duration, reason}
|
||||
* - 'webrtcConnectionCreated' {sessionId, timestamp, participantId, connection, [receivingFrom], audioEnabled, videoEnabled, [videoSource], [videoFramerate]}
|
||||
* - 'webrtcConnectionDestroyed' {sessionId, timestamp, participantId, startTime, endTime, duration, connection, [receivingFrom], audioEnabled, videoEnabled, [videoSource], [videoFramerate], reason}
|
||||
|
|
|
@ -26,19 +26,24 @@ public class Participant {
|
|||
private String clientMetadata = ""; // Metadata provided on client side
|
||||
private String serverMetadata = ""; // Metadata provided on server side
|
||||
private Token token; // Token associated to this participant
|
||||
private String location; // Remote IP of the participant
|
||||
private String platform; // Platform used by the participant to connect to the session
|
||||
|
||||
protected boolean streaming = false;
|
||||
protected volatile boolean closed;
|
||||
|
||||
private final String METADATA_SEPARATOR = "%/%";
|
||||
|
||||
public Participant(String participantPrivatetId, String participantPublicId, Token token, String clientMetadata) {
|
||||
public Participant(String participantPrivatetId, String participantPublicId, Token token, String clientMetadata,
|
||||
String location, String platform) {
|
||||
this.participantPrivatetId = participantPrivatetId;
|
||||
this.participantPublicId = participantPublicId;
|
||||
this.token = token;
|
||||
this.clientMetadata = clientMetadata;
|
||||
if (!token.getServerMetadata().isEmpty())
|
||||
this.serverMetadata = token.getServerMetadata();
|
||||
this.location = location;
|
||||
this.platform = platform;
|
||||
}
|
||||
|
||||
public String getParticipantPrivateId() {
|
||||
|
@ -81,6 +86,22 @@ public class Participant {
|
|||
this.token = token;
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
public void setLocation(String location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public String getPlatform() {
|
||||
return this.platform;
|
||||
}
|
||||
|
||||
public void setPlatform(String platform) {
|
||||
this.platform = platform;
|
||||
}
|
||||
|
||||
public boolean isStreaming() {
|
||||
return streaming;
|
||||
}
|
||||
|
@ -166,6 +187,8 @@ public class Participant {
|
|||
public JsonObject toJson() {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("connectionId", this.participantPublicId);
|
||||
json.addProperty("location", this.location);
|
||||
json.addProperty("platform", this.platform);
|
||||
json.addProperty("token", this.token.getToken());
|
||||
json.addProperty("role", this.token.getRole().name());
|
||||
json.addProperty("serverData", this.serverMetadata);
|
||||
|
|
|
@ -115,8 +115,9 @@ public abstract class SessionManager {
|
|||
|
||||
public abstract void removeFilterEventListener(Session session, Participant subscriber, String streamId,
|
||||
String eventType);
|
||||
|
||||
public abstract String getParticipantPrivateIdFromStreamId(String sessionId, String streamId) throws OpenViduException;
|
||||
|
||||
public abstract String getParticipantPrivateIdFromStreamId(String sessionId, String streamId)
|
||||
throws OpenViduException;
|
||||
|
||||
/**
|
||||
* Returns a Session given its id
|
||||
|
@ -331,10 +332,11 @@ public abstract class SessionManager {
|
|||
}
|
||||
|
||||
public Participant newParticipant(String sessionId, String participantPrivatetId, Token token,
|
||||
String clientMetadata) {
|
||||
String clientMetadata, String location, String platform) {
|
||||
if (this.sessionidParticipantpublicidParticipant.get(sessionId) != null) {
|
||||
String participantPublicId = this.generateRandomChain();
|
||||
Participant p = new Participant(participantPrivatetId, participantPublicId, token, clientMetadata);
|
||||
Participant p = new Participant(participantPrivatetId, participantPublicId, token, clientMetadata, location,
|
||||
platform);
|
||||
while (this.sessionidParticipantpublicidParticipant.get(sessionId).putIfAbsent(participantPublicId,
|
||||
p) != null) {
|
||||
participantPublicId = this.generateRandomChain();
|
||||
|
@ -350,7 +352,7 @@ public abstract class SessionManager {
|
|||
String clientMetadata) {
|
||||
if (this.sessionidParticipantpublicidParticipant.get(sessionId) != null) {
|
||||
Participant p = new Participant(participantPrivatetId, ProtocolElements.RECORDER_PARTICIPANT_PUBLICID,
|
||||
token, clientMetadata);
|
||||
token, clientMetadata, null, null);
|
||||
this.sessionidParticipantpublicidParticipant.get(sessionId)
|
||||
.put(ProtocolElements.RECORDER_PARTICIPANT_PUBLICID, p);
|
||||
return p;
|
||||
|
|
|
@ -80,7 +80,7 @@ public class KurentoParticipant extends Participant {
|
|||
public KurentoParticipant(Participant participant, KurentoSession kurentoSession, MediaPipeline pipeline,
|
||||
InfoHandler infoHandler, CallDetailRecord CDR, OpenviduConfig openviduConfig) {
|
||||
super(participant.getParticipantPrivateId(), participant.getParticipantPublicId(), participant.getToken(),
|
||||
participant.getClientMetadata());
|
||||
participant.getClientMetadata(), participant.getLocation(), participant.getPlatform());
|
||||
this.openviduConfig = openviduConfig;
|
||||
this.session = kurentoSession;
|
||||
this.pipeline = pipeline;
|
||||
|
@ -157,7 +157,7 @@ public class KurentoParticipant extends Participant {
|
|||
public synchronized void releaseAllFilters() {
|
||||
// Check this, mutable array?
|
||||
filters.forEach((s, filter) -> removeFilterElement(s));
|
||||
if(this.publisher.getFilter() != null) {
|
||||
if (this.publisher.getFilter() != null) {
|
||||
this.publisher.revert(this.publisher.getFilter());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package io.openvidu.server.rpc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
@ -25,6 +27,7 @@ import java.util.concurrent.ConcurrentMap;
|
|||
import org.kurento.jsonrpc.DefaultJsonRpcHandler;
|
||||
import org.kurento.jsonrpc.Session;
|
||||
import org.kurento.jsonrpc.Transaction;
|
||||
import org.kurento.jsonrpc.internal.ws.WebSocketServerSession;
|
||||
import org.kurento.jsonrpc.message.Request;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -34,6 +37,7 @@ import com.google.gson.JsonElement;
|
|||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.maxmind.geoip2.exception.GeoIp2Exception;
|
||||
|
||||
import io.openvidu.client.OpenViduException;
|
||||
import io.openvidu.client.OpenViduException.Code;
|
||||
|
@ -43,6 +47,7 @@ import io.openvidu.server.core.MediaOptions;
|
|||
import io.openvidu.server.core.Participant;
|
||||
import io.openvidu.server.core.SessionManager;
|
||||
import io.openvidu.server.core.Token;
|
||||
import io.openvidu.server.utils.GeoLocationByIpUtils;
|
||||
|
||||
public class RpcHandler extends DefaultJsonRpcHandler<JsonObject> {
|
||||
|
||||
|
@ -51,6 +56,9 @@ public class RpcHandler extends DefaultJsonRpcHandler<JsonObject> {
|
|||
@Autowired
|
||||
OpenviduConfig openviduConfig;
|
||||
|
||||
@Autowired
|
||||
GeoLocationByIpUtils geoLocationByIp;
|
||||
|
||||
@Autowired
|
||||
SessionManager sessionManager;
|
||||
|
||||
|
@ -159,8 +167,26 @@ public class RpcHandler extends DefaultJsonRpcHandler<JsonObject> {
|
|||
String sessionId = getStringParam(request, ProtocolElements.JOINROOM_ROOM_PARAM);
|
||||
String token = getStringParam(request, ProtocolElements.JOINROOM_TOKEN_PARAM);
|
||||
String secret = getStringParam(request, ProtocolElements.JOINROOM_SECRET_PARAM);
|
||||
String platform = getStringParam(request, ProtocolElements.JOINROOM_PLATFORM_PARAM);
|
||||
String participantPrivatetId = rpcConnection.getParticipantPrivateId();
|
||||
|
||||
InetAddress remoteAddress = null;
|
||||
String location = "";
|
||||
Object obj = rpcConnection.getSession().getAttributes().get("remoteAddress");
|
||||
if (obj != null && obj instanceof InetAddress) {
|
||||
remoteAddress = (InetAddress) obj;
|
||||
try {
|
||||
location = this.geoLocationByIp.getLocationByIp(remoteAddress);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
location = "error";
|
||||
} catch (GeoIp2Exception e) {
|
||||
log.warn("Error getting address location: {}", e.getMessage());
|
||||
location = "unknown";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
boolean recorder = false;
|
||||
|
||||
try {
|
||||
|
@ -193,7 +219,7 @@ public class RpcHandler extends DefaultJsonRpcHandler<JsonObject> {
|
|||
clientMetadata);
|
||||
} else {
|
||||
participant = sessionManager.newParticipant(sessionId, participantPrivatetId, tokenObj,
|
||||
clientMetadata);
|
||||
clientMetadata, location, platform);
|
||||
}
|
||||
|
||||
rpcConnection.setSessionId(sessionId);
|
||||
|
@ -521,6 +547,10 @@ public class RpcHandler extends DefaultJsonRpcHandler<JsonObject> {
|
|||
@Override
|
||||
public void afterConnectionEstablished(Session rpcSession) throws Exception {
|
||||
log.info("After connection established for WebSocket session: {}", rpcSession.getSessionId());
|
||||
if (rpcSession instanceof WebSocketServerSession) {
|
||||
rpcSession.getAttributes().put("remoteAddress",
|
||||
((WebSocketServerSession) rpcSession).getWebSocketSession().getRemoteAddress().getAddress());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
package io.openvidu.server.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.maxmind.db.Reader;
|
||||
import com.maxmind.geoip2.DatabaseReader;
|
||||
import com.maxmind.geoip2.exception.GeoIp2Exception;
|
||||
import com.maxmind.geoip2.model.CityResponse;
|
||||
|
||||
/**
|
||||
* This product includes GeoLite2 data created by MaxMind, available from
|
||||
* <a href="http://www.maxmind.com">http://www.maxmind.com</a>.
|
||||
*/
|
||||
|
||||
@Service("geolocationservice")
|
||||
public class GeoLocationByIpUtils {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(GeoLocationByIpUtils.class);
|
||||
|
||||
private static DatabaseReader reader = null;
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
@Inject
|
||||
public GeoLocationByIpUtils(ResourceLoader resourceLoader) {
|
||||
this.resourceLoader = resourceLoader;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
try {
|
||||
log.info("GeoLocationByIpUtils: Trying to load GeoLite2-City database...");
|
||||
Resource resource = resourceLoader.getResource("classpath:GeoLite2-City.mmdb");
|
||||
InputStream dbAsStream = resource.getInputStream();
|
||||
// Initialize the reader
|
||||
reader = new DatabaseReader.Builder(dbAsStream).fileMode(Reader.FileMode.MEMORY).build();
|
||||
log.info("GeoLocationServiceImpl: Database was loaded successfully");
|
||||
} catch (IOException | NullPointerException e) {
|
||||
log.error("Database reader cound not be initialized", e);
|
||||
}
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void preDestroy() {
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to close the GeoLocation reader");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getLocationByIp(InetAddress ipAddress) throws IOException, GeoIp2Exception {
|
||||
CityResponse response = reader.city(ipAddress);
|
||||
return response.getCity().getNames().get("en") + ", " + response.getCountry().getNames().get("en");
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 63 MiB |
|
@ -18,6 +18,6 @@
|
|||
<app-root>
|
||||
<mat-spinner></mat-spinner>
|
||||
</app-root>
|
||||
<script type="text/javascript" src="runtime.a66f828dca56eeb90e02.js"></script><script type="text/javascript" src="polyfills.3582350dd6075fd34141.js"></script><script type="text/javascript" src="main.a5878fcbbb284a79712e.js"></script></body>
|
||||
<script type="text/javascript" src="runtime.a66f828dca56eeb90e02.js"></script><script type="text/javascript" src="polyfills.3582350dd6075fd34141.js"></script><script type="text/javascript" src="main.a7de0bb357964fcc90fc.js"></script></body>
|
||||
|
||||
</html>
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue