Vuzix M100 和 Webrtc 错误:连接失败:EHOSTUNREACH(没有到主机的路由)
Posted
技术标签:
【中文标题】Vuzix M100 和 Webrtc 错误:连接失败:EHOSTUNREACH(没有到主机的路由)【英文标题】:Vuzix M100 and Webrtc Error: connect failed: EHOSTUNREACH (No route to host) 【发布时间】:2016-09-22 13:48:44 【问题描述】:这是我想要到达的 Szenario:
我想使用 vuzix m100 (android API 15) 和 Google Chrome 浏览器/或者 Firefox 开发 2 路远程视频会议。为了建立这个连接,我使用了 WebRTC 和一个带有 Websockets 的 Node.JS 服务器来启用两个客户端的查找。
我目前面临的问题是,如果我将 2 个 Chrome 浏览器客户端详细连接到一个 Android 设备(Sony Xperia z 3 紧凑型)和一个桌面电脑,那么一切都可以完美运行。 如果我尝试通过浏览器连接我的 Vuzix,我会收到没有主机路由的错误。
node.js 服务器:
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));
Android 应用:
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);
重要的是,错误出现在 initWebSockets 函数中
我得到的错误:
09-22 15:41:47.056 7682-7779/com.mobile_function.webrtc_android W/System.err: com.neovisionaries.ws.client.WebSocketException: Failed to connect to '192.168.179.36:9090': failed to connect to /192.168.179.36 (port 9090): connect failed: EHOSTUNREACH (No route to host)
09-22 15:41:47.056 7682-7779/com.mobile_function.webrtc_android W/System.err: at com.neovisionaries.ws.client.SocketConnector.doConnect(SocketConnector.java:119)
09-22 15:41:47.056 7682-7779/com.mobile_function.webrtc_android W/System.err: at com.neovisionaries.ws.client.SocketConnector.connect(SocketConnector.java:81)
09-22 15:41:47.064 7682-7779/com.mobile_function.webrtc_android W/System.err: at com.neovisionaries.ws.client.WebSocket.connect(WebSocket.java:2022)
09-22 15:41:47.064 7682-7779/com.mobile_function.webrtc_android W/System.err: at com.mobile_function.webrtc_android.ServerConnection$1.run(ServerConnection.java:84)
09-22 15:41:47.064 7682-7779/com.mobile_function.webrtc_android W/System.err: at java.lang.Thread.run(Thread.java:856)
09-22 15:41:47.064 7682-7779/com.mobile_function.webrtc_android W/System.err: Caused by: java.net.ConnectException: failed to connect to /192.168.179.36 (port 9090): connect failed: EHOSTUNREACH (No route to host)
09-22 15:41:47.071 7682-7779/com.mobile_function.webrtc_android W/System.err: at libcore.io.IoBridge.connect(IoBridge.java:114)
09-22 15:41:47.071 7682-7779/com.mobile_function.webrtc_android W/System.err: at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
09-22 15:41:47.071 7682-7779/com.mobile_function.webrtc_android W/System.err: at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
09-22 15:41:47.071 7682-7779/com.mobile_function.webrtc_android W/System.err: at java.net.Socket.connect(Socket.java:842)
09-22 15:41:47.071 7682-7779/com.mobile_function.webrtc_android W/System.err: at com.neovisionaries.ws.client.SocketConnector.doConnect(SocketConnector.java:110)
09-22 15:41:47.071 7682-7779/com.mobile_function.webrtc_android W/System.err: ... 4 more
09-22 15:41:47.071 7682-7779/com.mobile_function.webrtc_android W/System.err: Caused by: libcore.io.ErrnoException: connect failed: EHOSTUNREACH (No route to host)
09-22 15:41:47.079 7682-7779/com.mobile_function.webrtc_android W/System.err: at libcore.io.Posix.connect(Native Method)
09-22 15:41:47.079 7682-7779/com.mobile_function.webrtc_android W/System.err: at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:85)
09-22 15:41:47.079 7682-7779/com.mobile_function.webrtc_android W/System.err: at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
09-22 15:41:47.079 7682-7779/com.mobile_function.webrtc_android W/System.err: at libcore.io.IoBridge.connect(IoBridge.java:112)
09-22 15:41:47.079 7682-7779/com.mobile_function.webrtc_android W/System.err: ... 8 more
我在某些主题中搜索了有关这些错误代码的信息。 我的 WiFi 连接已启用,我可以使用我的 Vuzix 玻璃通过 mozilla firefox 访问不同的网页,但我无法访问我的服务器。
这两个客户端肯定在同一个子网中: 安卓:192.168.179.94 WebApp 的 html 服务器:192.168.179.36:8080 节点套接字服务器:192.168.179.36:9090 网关:192.168.179.1
我希望任何人都可以给我一些建议,我该如何解决这个问题
亲切的问候
jmd
【问题讨论】:
【参考方案1】:解决了问题。帮助我解决问题的链接:http://forum.airdroid.com/discussion/379/i-can-t-even-ping-my-phone
亲切的问候约翰
【讨论】:
以上是关于Vuzix M100 和 Webrtc 错误:连接失败:EHOSTUNREACH(没有到主机的路由)的主要内容,如果未能解决你的问题,请参考以下文章
WebRTC 无法在控制台上的 RTCPeerConnection 错误上执行“addIceCandidate”,但仍可以显示远程和本地视频