这是我想要达到的Szenario:
我想开发一个带有vuzix m100(Android API 15)和Google Chrome浏览器/ Firefox的双向远程视频会议。为了实现这种连接,我使用WebRTC和带有Websockets的Node.JS服务器来启用两个客户端的查找。
我目前面临的问题是,如果我将2个Chrome浏览器客户端详细连接到Android设备(Sony Xperia z 3 compact)和Deskop Pc,那么这一切都非常完美。 如果我尝试通过浏览器连接我的Vuzix,我收到的错误是没有路由来托管。
node.js服务器:
const face = new cognitiveServices.face({
^
TypeError: cognitiveServices.face is not a constructor
at Object.<anonymous> (/Users/..../face.js:3:14)
at Module._compile (module.js:556:32)
at Object.Module._extensions..js (module.js:565:10)
at Module.load (module.js:473:32)
at tryModuleLoad (module.js:432:12)
at Function.Module._load (module.js:424:3)
at Module.runMain (module.js:590:10)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:509:3
Android应用
var fs = require('fs');
var https = require('https');
var privateKey = fs.readFileSync('server.key', 'utf8');
var certificate = fs.readFileSync('server.crt', 'utf8');
var credentials = {key: privateKey, cert: certificate};
var express = require('express');
var app = express();
//require our websocket library
var WebSocketServer = require('ws').Server;
var httpsServer = https.createServer(credentials, app);
httpsServer.listen(9090);
//creating a websocket server at port 9090
// var wss = new WebSocketServer({port: 9090}, {});
var wss = new WebSocketServer({
server : httpsServer
})
//all connected to the server users
var users = {};
//when a user connects to our sever
wss.on('connection', function(connection) {
console.log("User connected");
//when server gets a message from a connected user
connection.on('message', function(message) {
var data;
//accepting only JSON messages
try {
data = JSON.parse(message);
} catch (e) {
console.log("Invalid JSON");
data = {};
}
//switching type of the user message
switch (data.type) {
//when a user tries to login
case "login":
console.log("User logged", data.name);
//if anyone is logged in with this username then refuse
if(users[data.name]) {
sendTo(connection, {
type: "login",
success: false
});
} else {
//save user connection on the server
users[data.name] = connection;
connection.name = data.name;
sendTo(connection, {
type: "login",
success: true
});
}
break;
case "offer":
//for ex. UserA wants to call UserB
console.log("Sending offer to: ", data.name);
//if UserB exists then send him offer details
var conn = users[data.name];
if(conn != null) {
//setting that UserA connected with UserB
connection.otherName = data.name;
sendTo(conn, {
type: "offer",
offer: data.offer,
name: connection.name
});
}
break;
case "answer":
console.log("Sending answer to: ", data.name);
//for ex. UserB answers UserA
var conn = users[data.name];
if(conn != null) {
connection.otherName = data.name;
sendTo(conn, {
type: "answer",
answer: data.answer
});
}
break;
case "candidate":
console.log("Sending candidate to:",data.name);
var conn = users[data.name];
if(conn != null) {
sendTo(conn, {
type: "candidate",
candidate: data.candidate
});
}
break;
case "leave":
console.log("Disconnecting from", data.name);
var conn = users[data.name];
conn.otherName = null;
//notify the other user so he can disconnect his peer connection
if(conn != null) {
sendTo(conn, {
type: "leave"
});
}
break;
default:
sendTo(connection, {
type: "error",
message: "Command not found: " + data.type
});
break;
}
});
//when user exits, for example closes a browser window
//this may help if we are still in "offer","answer" or "candidate" state
connection.on("close", function() {
if(connection.name) {
delete users[connection.name];
if(connection.otherName) {
console.log("Disconnecting from ", connection.otherName);
var conn = users[connection.otherName];
conn.otherName = null;
if(conn != null) {
sendTo(conn, {
type: "leave"
});
}
}
}
});
connection.send("Hello world");
});
function sendTo(connection, message) {
connection.send(JSON.stringify(message));
}
重要的是,initWebSockets函数中的错误掩码
我得到的错误:
public class ServerConnection {
private WebSocketFactory webSocketfactory;
private WebSocket ws;
private MediaStream mS;
private PeerConnectionFactory peerFactory;
private PeerConnection yourConn;
private MediaConstraints sdpConstraints;
private SessionObserver sessionObserver = new SessionObserver();
private PeerObserver peerObserver = new PeerObserver();
private String connectedUser;
public ServerConnection(MediaStream mS, PeerConnectionFactory peerFactory) {
this.webSocketfactory = new WebSocketFactory();
this.mS = mS;
this.peerFactory = peerFactory;
// Create a custom SSL context.
SSLContext context = null;
try {
context = NaiveSSLContext.getInstance("TLS");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
// Set the custom SSL context.
webSocketfactory.setSSLContext(context);
initWebsockets();
}
public void sendMessage(String message) {
if (connectedUser != null) {
try {
JSONObject json = new JSONObject(message);
json.put("name", connectedUser);
ws.sendText(json.toString());
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("String s", message);
ws.sendText(message);
}
}
private void initWebsockets() {
try {
ws = webSocketfactory.createSocket("wss://192.168.179.36:9090");
ws.addListener(new SocketListener());
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
ws.connect();
} catch (WebSocketException e) {
e.printStackTrace();
initWebsockets();
}
}
});
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
class SocketListener extends WebSocketAdapter {
@Override
public void onConnected(WebSocket websocket, Map<String, List<String>> headers) throws Exception {
Log.e("connected", "connected");
JSONObject json = new JSONObject();
try {
// Für den Anfang statisch
json.put("type", "login");
json.put("name", "John");
} catch (JSONException e) {
e.printStackTrace();
}
sendMessage(json.toString());
}
@Override
public void onConnectError(WebSocket websocket, WebSocketException exception) throws Exception {
Log.e("onError", exception.getMessage());
}
@Override
public void onDisconnected(WebSocket websocket,
WebSocketFrame serverCloseFrame, WebSocketFrame clientCloseFrame,
boolean closedByServer) throws Exception {
}
@Override
public void onTextMessage(WebSocket websocket, String text) throws Exception {
Log.e("Got Message", text);
JSONObject json = new JSONObject(text);
if (json != null) {
switch (json.getString("type")) {
case "login":
Log.e("Condition", json.getString("success"));
handleLogin(json.getBoolean("success"));
break;
case "offer":
handleOffer(json.getString("offer"), json.getString("name"));
break;
case "answer":
handleAnswer(json.getString("answer"));
break;
case "candidate":
String candidate = json.getString("candidate");
handleCandidate(candidate);
break;
case "leave":
break;
default:
break;
}
}
}
@Override
public void onFrameSent(WebSocket websocket, WebSocketFrame frame) throws Exception {
Log.e("sent", frame.getPayloadText());
}
}
private void handleLogin(boolean success) {
if (!success) {
Log.e("handleLogin", "Try a different Username");
} else {
List<PeerConnection.IceServer> server = new ArrayList<>();
server.add(new PeerConnection.IceServer("stun:stun2.1.google.com:19302"));
server.add(new PeerConnection.IceServer("turn:192.158.29.39:3478?transport=udp", "28224511:1379330808", "JZEOEt2V3Qb0y27GRntt2u2PAYA="));
sdpConstraints = new MediaConstraints();
sdpConstraints.optional.add(new MediaConstraints.KeyValuePair("offerToReceiveAudio", "true"));
sdpConstraints.optional.add(new MediaConstraints.KeyValuePair("offerToReceiveVideo", "true"));
yourConn = peerFactory.createPeerConnection(server, sdpConstraints, peerObserver);
Log.e("Media Stream:", mS.toString());
yourConn.addStream(mS);
// wird später implementiert um anrufe zu starten
// yourConn.createOffer(new SessionObserver(), sdpConstraints);
}
}
private void handleOffer(String offer, String name) {
try {
JSONObject sdp = new JSONObject(offer);
connectedUser = name;
SessionDescription sessionDescription = new SessionDescription(SessionDescription.Type.OFFER, sdp.getString("sdp"));
yourConn.setRemoteDescription(sessionObserver, sessionDescription);
yourConn.createAnswer(sessionObserver, sdpConstraints);
} catch (JSONException e) {
e.printStackTrace();
}
}
private void handleAnswer(String answer) {
try {
Log.e("answer", answer);
JSONObject sdp = new JSONObject(answer);
SessionDescription sessionDescription = new SessionDescription(SessionDescription.Type.ANSWER, sdp.getString("sdp"));
yourConn.setRemoteDescription(sessionObserver, sessionDescription);
} catch (JSONException e) {
e.printStackTrace();
}
}
private void handleLeave() {
}
private void handleCandidate(String candidate) {
Log.e("handleCandidate", candidate);
//yourConn.addIceCandidate(new IceCandidate())
// try {
// JSONObject candidateJson = new JSONObject();
// candidateJson.put("type", "candidate");
// JSONObject candidateInfosJSON = new JSONObject(candidate);
// candidateJson.put("candidate", candidateInfosJSON);
//
// sendMessage(candidateJson.toString());
// } catch (JSONException e) {
// e.printStackTrace();
// }
}
class PeerObserver implements PeerConnection.Observer {
@Override
public void onSignalingChange(PeerConnection.SignalingState signalingState) {
Log.e("onSignalingChange", "");
}
@Override
public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) {
Log.e("onIceConnectionChange", "");
}
@Override
public void onIceConnectionReceivingChange(boolean b) {
Log.e("onIceConnectionChange", "");
}
@Override
public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) {
Log.e("onIceGatheringChange", "");
}
@Override
public void onIceCandidate(IceCandidate iceCandidate) {
// Log.e("onIceCandidate", iceCandidate.toString());
// JSONObject candidate = new JSONObject();
// try {
//
// candidate.put("type", "candidate");
// candidate.put("label", iceCandidate.sdpMLineIndex);
// candidate.put("id", iceCandidate.sdpMid);
// candidate.put("candidate", iceCandidate);
Log.e("OnIceCandidate", "here");
// } catch (JSONException e) {
// e.printStackTrace();
// }
}
@Override
public void onAddStream(MediaStream mediaStream) {
Log.e("onAddStream", "Stream added: " + mediaStream);
}
@Override
public void onRemoveStream(MediaStream mediaStream) {
Log.e("onRemoveStream", "Removed mediaStream: " + mediaStream);
}
@Override
public void onDataChannel(DataChannel dataChannel) {
Log.e("onDataChannel", "");
}
@Override
public void onRenegotiationNeeded() {
Log.e("onRenegotiationNeeded", "");
}
}
class SessionObserver implements SdpObserver {
@Override
public void onCreateSuccess(SessionDescription sessionDescription) {
Log.e("Session", "sending");
JSONObject session = new JSONObject();
JSONObject answer = new JSONObject();
try {
String answerORoffer = sessionDescription.type.toString().toLowerCase();
session.put("type", answerORoffer);
answer.put("type", answerORoffer);
answer.put("sdp", sessionDescription.description);
session.put(answerORoffer, answer);
Log.e("SESSION", session.toString());
//session.put(answerORoffer, sessionDescription.description);
sendMessage(session.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onSetSuccess() {
Log.e("do call success", ".....");
}
@Override
public void onCreateFailure(String s) {
Log.e("do call failure", s);
}
@Override
public void onSetFailure(String s) {
Log.e("onSetFailure", s);
}
}
}
我在某些主题中搜索过这些错误代码。 我的WiFi连接已启用,我可以使用我的Vuzix玻璃通过mozilla firefox访问不同的网页,但我无法访问我的服务器。
这两个客户端最终位于同一个子网中: Android:192.168.179.94 WebApp的Html Server:192.168.179.36:8080 节点套接字服务器:192.168.179.36:9090 网关:192.168.179.1
我希望任何人都可以给我一些建议如何解决这个问题
亲切的问候
JMD
答案 0 :(得分:0)
解决了问题。帮助我解决问题的链接:http://forum.airdroid.com/discussion/379/i-can-t-even-ping-my-phone
亲切的问候约翰