Java 在J2EE应用程序中使用webRTC进行视频会议
我需要向使用J2EE技术开发并部署在JBoss服务器中的网站添加视频会议功能。 经过多次研究,我发现了WebRTC,但我想知道如何将其用于jboss,因为大多数示例都将其用于node.js 一个简单的代码示例将非常有用。 多谢各位 编辑Java 在J2EE应用程序中使用webRTC进行视频会议,java,jboss,webrtc,video-conferencing,Java,Jboss,Webrtc,Video Conferencing,我需要向使用J2EE技术开发并部署在JBoss服务器中的网站添加视频会议功能。 经过多次研究,我发现了WebRTC,但我想知道如何将其用于jboss,因为大多数示例都将其用于node.js 一个简单的代码示例将非常有用。 多谢各位 编辑 我尝试过webRTC,但在信号部分遇到了一些问题: 我使用webSocket,这是我的类码 package com.bean; import java.io.IOException; import java.util.Hashtable; import java
我尝试过webRTC,但在信号部分遇到了一些问题:
我使用webSocket,这是我的类码
package com.bean;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.bean.ApplicationScoped;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.json.JSONException;
import org.json.JSONObject;
@ApplicationScoped
@ServerEndpoint("/webrtc")
public class WebRTCSocket {
public static Map < String, Hashtable < String, Object[] >> sessionMap = new Hashtable < String, Hashtable < String, Object[] >> ();
@SuppressWarnings("unchecked")
@OnMessage
public void message(String message, Session session) {
System.out.println("entre a la methode");
try {
JSONObject jsonObject = new JSONObject(message);
try {
Object isOpen = jsonObject.get("open");
if (isOpen != null && (Boolean) isOpen == true) {
String channel = (String) jsonObject.get("channel");
Object value = sessionMap.get(channel);
Hashtable < String, Object[] > sourceDestMap = null;
if (value == null) {
sourceDestMap = new Hashtable < String, Object[] > ();
} else sourceDestMap = (Hashtable < String, Object[] > ) value;
sourceDestMap.put(session.getId(), new Object[] {
session
});
sessionMap.put(channel, sourceDestMap);
}
} catch (JSONException je) {
je.printStackTrace();
}
try {
Object dataObj = jsonObject.get("data");
JSONObject dataMapObj = (JSONObject) dataObj;
//Object thisUserId = dataMapObj.get("userid");
String channel = null;
try {
channel = (String) dataMapObj.get("sessionid");
} catch (JSONException json) {
channel = (String) jsonObject.get("channel");
}
/*
JSONObject dataMapObj = (JSONObject) dataObj;
Object thisUserId = dataMapObj.get("userid");
String channel = (String) dataMapObj.get("sessionid");
Hashtable < string, object > sourceDestMap = sessionMap.get(channel);
if (thisUserId != null && sourceDestMap.get((String) thisUserId) == null) {
sourceDestMap.put((String) thisUserId, new Object[] {
message, session
});
}
for (String userId: sourceDestMap.keySet()) {
if (!userId.equals(thisUserId)) {
Session otherSession = (Session)((Object[]) sourceDestMap.get(userId))[1];
otherSession.getBasicRemote().sendText(message);
}
}
*/
Hashtable < String, Object[] > sourceDestMap = sessionMap.get(channel);
if (sourceDestMap != null)
for (String id: sourceDestMap.keySet()) {
if (!id.equals(session.getId())) {
Session otherSession = (Session)((Object[]) sourceDestMap.get(id))[0];
if (otherSession.isOpen())
otherSession.getBasicRemote().sendText(dataMapObj.toString());
}
}
} catch (JSONException je) {
je.printStackTrace();
}
} catch (JSONException je) {
je.printStackTrace();
}
catch (IOException je) {
je.printStackTrace();
}
System.out.println("Message received:" + message);
}
@OnOpen
public void open(Session session) {
System.out.println("Channel opened");
}
// need to implement @OnClose too
@OnError
public void onError(Throwable error) {
Logger.getLogger(WebRTCSocket.class.getName()).log(Level.SEVERE, null, error);
}
}
package.com.bean;
导入java.io.IOException;
导入java.util.Hashtable;
导入java.util.Map;
导入java.util.logging.Level;
导入java.util.logging.Logger;
导入javax.faces.bean.ApplicationScoped;
导入javax.websocket.OnError;
导入javax.websocket.OnMessage;
导入javax.websocket.OnOpen;
导入javax.websocket.Session;
导入javax.websocket.server.ServerEndpoint;
导入org.json.JSONException;
导入org.json.JSONObject;
@适用范围
@ServerEndpoint(“/webrtc”)
公共类WebRTCSocket{
公共静态映射>sessionMap=newhashtable>();
@抑制警告(“未选中”)
@OnMessage
公共无效消息(字符串消息、会话){
系统输出打印(“entre a la methode”);
试一试{
JSONObject JSONObject=新的JSONObject(消息);
试一试{
对象isOpen=jsonObject.get(“打开”);
if(isOpen!=null&(布尔)isOpen==true){
字符串通道=(字符串)jsonObject.get(“通道”);
对象值=sessionMap.get(通道);
HashtablesourceDestMap=null;
如果(值==null){
sourceDestMap=newhashtable();
}else sourceDestMap=(Hashtable)值;
sourceDestMap.put(session.getId(),新对象[]{
一场
});
sessionMap.put(频道,sourceDestMap);
}
}捕获(JSONException je){
je.printStackTrace();
}
试一试{
objectdataobj=jsonObject.get(“数据”);
JSONObject dataMapObj=(JSONObject)dataObj;
//对象thisUserId=dataMapObj.get(“userid”);
字符串通道=空;
试一试{
通道=(字符串)dataMapObj.get(“sessionid”);
}捕获(JSONException json){
通道=(字符串)jsonObject.get(“通道”);
}
/*
JSONObject dataMapObj=(JSONObject)dataObj;
对象thisUserId=dataMapObj.get(“userid”);
字符串通道=(字符串)dataMapObj.get(“sessionid”);
HashtablesourceDestMap=sessionMap.get(通道);
if(thisUserId!=null&&sourceDestMap.get((字符串)thisUserId)==null){
sourceDestMap.put((字符串)thisUserId,新对象[]{
信息、会话
});
}
for(字符串userId:sourceDestMap.keySet()){
如果(!userId.equals(thisUserId)){
Session otherSession=(Session)((Object[])sourceDestMap.get(userId))[1];
otherSession.getBasicRemote().sendText(消息);
}
}
*/
HashtablesourceDestMap=sessionMap.get(通道);
if(sourceDestMap!=null)
for(字符串id:sourceDestMap.keySet()){
如果(!id.equals(session.getId())){
Session otherSession=(Session)((Object[])sourceDestMap.get(id))[0];
if(otherSession.isOpen())
otherSession.getBasicRemote().sendText(dataMapObj.toString());
}
}
}捕获(JSONException je){
je.printStackTrace();
}
}捕获(JSONException je){
je.printStackTrace();
}
捕获(IOJE例外){
je.printStackTrace();
}
System.out.println(“收到的消息:+消息”);
}
@奥诺彭
公开作废开放(会议){
System.out.println(“频道打开”);
}
//还需要实现@OnClose吗
@一个错误
公共无效onError(可丢弃错误){
Logger.getLogger(WebRTCSocket.class.getName()).log(Level.SEVERE,null,error);
}
}
这是我的xhtml页面
<html>
<head>
</head>
<body>
<script >
var localVideo;
var remoteVideo;
var peerConnection;
var peerConnectionConfig = {'iceServers': [{'url': 'stun:stun.services.mozilla.com'}, {'url': 'stun:stun.l.google.com:19302'}]};
navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
window.RTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate || window.webkitRTCIceCandidate;
window.RTCSessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription || window.webkitRTCSessionDescription;
function pageReady() {
localVideo = document.getElementById('localVideo');
remoteVideo = document.getElementById('remoteVideo');
serverConnection = new WebSocket('ws://localhost:8080/jasper/webrtc');
console.log('serverConnection' + serverConnection.url);
serverConnection.onmessage = gotMessageFromServer;
var constraints = {
video: true,
audio: true,
};
if(navigator.getUserMedia) {
navigator.getUserMedia(constraints, getUserMediaSuccess, errorHandler);
} else {
alert('Your browser does not support getUserMedia API');
}
}
function getUserMediaSuccess(stream) {
localStream = stream;
localVideo.src = window.URL.createObjectURL(stream);
}
function start(isCaller) {
peerConnection = new RTCPeerConnection(peerConnectionConfig);
peerConnection.onicecandidate = gotIceCandidate;
peerConnection.onaddstream = gotRemoteStream;
peerConnection.addStream(localStream);
if(isCaller) {
peerConnection.createOffer(gotDescription, errorHandler);
}
}
function gotMessageFromServer(event) {
console.log('gotMessageFromServer' + JSON.parse(event.data));
if(!peerConnection) start(false);
var signal = JSON.parse(event.data);
if(signal.sdp) {
peerConnection.setRemoteDescription(new RTCSessionDescription(signal.sdp), function() {
peerConnection.createAnswer(gotDescription, errorHandler);
}, errorHandler);
} else if(signal.ice) {
peerConnection.addIceCandidate(new RTCIceCandidate(signal.ice));
}
}
function gotIceCandidate(event) {
if(event.candidate != null) {
serverConnection.send(JSON.stringify({'ice': event.candidate}));
}
}
function gotDescription(description) {
console.log('got description');
peerConnection.setLocalDescription(description, function () {
serverConnection.send(JSON.stringify({'sdp': description}));
}, function() {console.log('set description error')});
}
function gotRemoteStream(event) {
console.log('got remote stream');
remoteVideo.src = window.URL.createObjectURL(event.stream);
}
function errorHandler(error) {
console.log(error);
}
</script>
<video id="localVideo" autoplay="autoplay" style="width:40%;"></video>
<video id="remoteVideo" autoplay style="width:40%;"></video>
<br />
<input type="button" id="start" onclick="start(true)" value="Start Video"></input>
<script type="text/javascript">
pageReady();
</script>
</body>
</html>
本地视频;
远程视频;
var-peerConnection;
var peerConnectionConfig={'iceServers':[{'url':'stun:stun.services.mozilla.com'},{'url':'stun:stun.l.google.com:19302'};
navigator.getUserMedia=navigator.getUserMedia | | navigator.mozGetUserMedia | | navigator.webkitGetUserMedia;
window.rtpeerconnection=window.rtpeerconnection | | window.mozrtpeerconnection | | window.webkirtpeerconnection;
window.RTCIceCandidate=window.RTCIceCandidate | | window.mozRTCIceCandidate | | | window.webkirtcicecandidate;
window.RTCSessionDescription=window.RTCSessionDescription | | window.mozRTCSessionDescription | | window.webkittcsessiondescription;
函数pageReady(){
localVideo=document.getElementById('localVideo');
remoteVideo=document.getElementById('remoteVideo');
serverConnection=newwebsocket('ws://localhost:8080/jasper/webrtc');
log('serverConnection'+serverConnection.url);
serverConnection.onmessage=gotMessageFromServer;
变量约束={
视频:没错,
音频:是的,
};
if(navigator.getUserMedia){
getUserMedia(约束,getUs
<dependency>
<groupId>org.jboss.spec.javax.websocket</groupId>
<artifactId>jboss-websocket-api_1.0_spec</artifactId>
<version>1.0.0.Final</version>
<scope>provided</scope>
</dependency>
package org.acode;
import java.util.Hashtable;
import java.util.Map;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.json.JSONException;
import org.json.JSONObject;
@ServerEndpoint("/webrtc")
public class WebRTCSocket {
public static Map<String, Hashtable<String, Object[]>> sessionMap = new Hashtable<>();
@OnMessage
public void message(String message, Session session) {
try {
System.out.println("receive message: " + message);
JSONObject jsonObject = new JSONObject(message);
String channel = null;
JSONObject dataMapObj = null;
Hashtable<String, Object[]> sourceDestMap = null;
try {
boolean isOpen = jsonObject.optBoolean("open");
channel = (String) jsonObject.get("channel");
sourceDestMap = (Hashtable<String, Object[]>) sessionMap.get(channel);
if (sourceDestMap == null) {
sourceDestMap = new Hashtable<String, Object[]>();
}
if (isOpen) {
/* Открытие канала */
sourceDestMap.put(session.getId(), new Object[]{session});
sessionMap.put(channel, sourceDestMap);
} else {
/*Остальные переговоры*/
dataMapObj = jsonObject.optJSONObject("data");
if (dataMapObj != null) {
sourceDestMap = sessionMap.get(channel);
for (String id : sourceDestMap.keySet()) {
if (!id.equals(session.getId())) {
Session otherSession = (Session) ((Object[]) sourceDestMap.get(id))[0];
if (otherSession.isOpen()) {
otherSession.getBasicRemote().sendText(dataMapObj.toString());
}
}
}
}
}
} catch (Exception je) {
je.printStackTrace();
}
} catch (JSONException je) {
je.printStackTrace();
}
}
@OnOpen
public void open(Session session
) {
System.out.println("Channel opened");
}
// need to implement @OnClose too
}
var SIGNALING_SERVER = "ws://192.168.1.46:8080/webrtc";
connection.openSignalingChannel = function (config) {
config.channel = config.channel || this.channel;
var websocket = new WebSocket(SIGNALING_SERVER);
websocket.channel = config.channel;
websocket.onopen = function () {
websocket.push(JSON.stringify({
open: true,
channel: config.channel
}));
if (config.callback)
config.callback(websocket);
};
websocket.onmessage = function (event) {
config.onmessage(JSON.parse(event.data));
};
websocket.push = websocket.send;
websocket.send = function (data) {
websocket.push(JSON.stringify({
data: data,
channel: config.channel
}));
};
};