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 错误:Ice 连接失败

web技术分享| 实现WebRTC多个对等连接

web技术分享| 实现WebRTC多个对等连接

WebRTC 无法在控制台上的 RTCPeerConnection 错误上执行“addIceCandidate”,但仍可以显示远程和本地视频

无法在 node.js 中建立对等 webrtc 连接

M100 无线数传