2016-12-09 14 views
1

ラズベリーパイで実行されているサーバーでwebsocketを設定しようとしています。次のコードは、私が見つけた例であるhereから若干修正されています。モバイルデバイスでwebsocketを開くことができません

私はこの例を中心に全体のWebページを構築して、gpioを制御し、piに接続されたシリアルデバイスにメッセージを送信できるようにしました。このサイトとこの例はともに私のラップトップ(ChromeまたはFirefoxを使用しているWindows 10)から完全に機能します。

ただし、携帯電話(Android 5.0.1はAndroid用Chromeを使用)から接続します。ソケットを決して開けないようです。サンプルコードでは、単に「メッセージはここに表示されます」

私の最初の考えはアンドロイドのWebSocketをサポートしていませんでしたが、このサイトに接続してメッセージをエコーすることができましたhttp://www.websocket.org/echo.html。開口部からソケットを妨げる他に何。

pysocket.py

import tornado.httpserver 
import tornado.websocket 
import tornado.ioloop 
import tornado.web 

class WSHandler(tornado.websocket.WebSocketHandler): 

    def check_origin(self, origin): 
    return True 

    def open(self): 
    print 'New connection was opened' 
    self.write_message("Welcome to my websocket!") 

    def on_message(self, message): 
    print 'Incoming message:', message 
    self.write_message("You said: " + message) 

    def on_close(self): 
    print 'Connection was closed...' 

application = tornado.web.Application([ 
    (r'/ws', WSHandler), 
]) 

if __name__ == "__main__": 
    http_server = tornado.httpserver.HTTPServer(application) 
    http_server.listen(8888) 
    tornado.ioloop.IOLoop.instance().start() 

pysocket.php

<!doctype html> 
<html> 
    <head> 
    <title>WebSockets with Python & Tornado</title> 
    <meta charset="utf-8" /> 
    <style type="text/css"> 
     body { 
     text-align: center; 
     min-width: 500px; 
     } 
    </style> 
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> 
    <script> 
     $(function(){ 
     var ws; 
     var logger = function(msg){ 
      var now = new Date(); 
      var sec = now.getSeconds(); 
      var min = now.getMinutes(); 
      var hr = now.getHours(); 
      $("#log").html($("#log").html() + "<br/>" + hr + ":" + min + ":" + sec + " ___ " + msg); 
      //$("#log").animate({ scrollTop: $('#log')[0].scrollHeight}, 100); 
      $('#log').scrollTop($('#log')[0].scrollHeight); 
     } 

     var sender = function() { 
      var msg = $("#msg").val(); 
      if (msg.length > 0) 
      ws.send(msg); 
      $("#msg").val(msg); 
     } 

     ws = new WebSocket("ws://raspberrypi-mike:8888/ws"); 
     ws.onmessage = function(evt) { 

      logger(evt.data); 
     }; 
     ws.onclose = function(evt) { 
      $("#log").text("Connection was closed..."); 
      $("#thebutton #msg").prop('disabled', true); 
     }; 
     ws.onopen = function(evt) { $("#log").text("Opening socket..."); }; 

     $("#msg").keypress(function(event) { 
      if (event.which == 13) { 
      sender(); 
      } 
     }); 

     $("#thebutton").click(function(){ 
      sender(); 
     }); 
     }); 
    </script> 
    </head> 

    <body> 
    <h1>WebSockets with Python & Tornado</h1> 
    <div id="log" style="overflow:scroll;width:500px; height:200px;background-color:#ffeeaa; margin:auto; text-align:left">Messages go here</div> 

    <div style="margin:10px"> 
     <input type="text" id="msg" style="background:#fff;width:200px"/> 
     <input type="button" id="thebutton" value="Send" /> 
    </div> 

    <a href="http://lowpowerlab.com/blog/2013/01/17/raspberrypi-websockets-with-python-tornado/">www.LowPowerLab.com</a> 
    </body> 
</html> 
+0

'raspberrypi-mike'の代わりにラズベリーパイのIPを使ってみましたか? –

+0

私はしていません。私は今夜​​それを試みます。私はノートパソコンが接続できるので、ホスト名が動いていると思った。私の電話にホスト名の代わりにIPが必要な特別な理由はありますか? – CrimsonKnights

+0

ホスト名をipに置き換えると問題が解決しました。今、私の携帯電話のブラウザがホスト名を解決できなかったのは本当に不思議です。 – CrimsonKnights

答えて

0

ネットワーク上でデバイスのホスト名を動作させるには、デバイスが独自のホスト名をアドバタイズするか、独自のホスト名に対してDNSクエリに応答する必要があります。

ラズベリーパイが使用している実装は、ラップトップでサポートされていますが、お使いの携帯電話はサポートしていません。

接続できるようにするには、JavaScriptコード内のホスト名raspberrypi-mikeをRaspberry PiのIPアドレスに変更する必要があります。

1

は、いくつかの余分なコードに

を追加しました私はそのためのNode.jsを使用することをお勧めします:

var express = require("express"); 
var app = express(); 
var http = require("http").Server(app); 
var path = require("path"); 
var io = require('socket.io')(http); 
var SerialPort = require('serialport'); 
var gpio = require('rpio'); 

http.listen(3000); 

var serialPort = new SerialPort.SerialPort("/dev/ttyAMA0", { 
    baudrate: 115200, 
    dataBits: 8, 
    parity: "none", 
    stopBits: 1, 
    flowControl: false 
}); 

io.on('connection', function(socket){ 
    console.log('Connected'); 
    socket.on("WriteSerial:get",function(data){ 
      var hex = new Buffer (data, "hex"); //be careful passing data 
      writeSerial(serialPort, hex); 
      io.emit("WriteSerial:response", "Data writen!"); 
    }); 
    socket.on("ReadGPIO:get",function(data){ 
      var input = readPin(data.pin); 
      io.emit("ReadGPIO:response", input); 
    }); 
    socket.on("WriteGPIO:get",function(data){ 
      writePin(data.pin, data.time); 
      io.emit("WriteGPIO:response", "Set!"); 
    }); 
    socket.on("unWriteGPIO:get",function(data){ 
      unwritePin(data); 
      io.emit("unWriteGPIO:response", "Set!"); 
    });   
} 
app.use(express.static(path.join(__dirname, '/'))); 
app.get("/home",function(req,res,next){ 
    res.sendFile(path.join(__dirname + "/index.html")); 
}); 

function writeSerial (port, data) { 
    port.write(data, function(err) { 
     if (err) { 
      return console.log('Error on write: ', err.message); 
     } else { 
      console.log('Data written: ' + data); 
     } 
    }); 
} 

function readPin(pin){ 
    rpio.open(pin, rpio.INPUT); 
    var read = rpio.read(pin) ? 'high' : 'low'; 
    return read; 
} 

function writePin(pin, timeInMs){ 
    rpio.open(pin, rpio.OUTPUT, rpio.LOW); 
    rpio.write(pin, rpio.HIGH); 
    if (timeInMs > 0) { 
     setTimeout(function(){ 
      rpio.write(pin, rpio.LOW); 
     }, timeInMs); 
    } //You can put 0 if You want it to be high until You shut it down 
} 

function unWritePin(pin){ 
    if(readPin(pin) === 'high') { 
     rpio.write(pin, rpio.LOW); 
    } else { 
     console.log("Pin already low!"); 
    } 
} 

は、あなたが正しいバージョンでのNode.jsをinstaledていることを確認してください。そうでない場合は、端末で次の操作を行います。apt-getをapt-getのnodejsのnodejs-レガシー& & カール-SL https://deb.nodesource.com/setup_4.xを削除& & nodered sudoを削除

sudoを| sudo bashの - & &須藤 apt-getをインストール-y nodejs

、 '/ホーム/ PI /' でフォルダ 'サーバー' を作成し、それにserver.jsを追加します。私がserver.jsに提供したコードを追加してください。ターミナルでそのフォルダを開きます。

CD /ホーム/ PI /サーバー/サーバー上で使用されるすべてのモジュールのインストール

Afther:急行& & sudoのNPMインストールインストール

sudoのNPMをhttp & & sudo npmインストールパス& & sudo npm install socket.io & & sudoのNPMがSERIALPORT --unsafe、パーマをインストール& & sudoのNPMインストールRPIO --unsafe-パーマ

今、私たちがしなければならないすべては、クライアント側の一部を作成することです。 '/ home/pi/server'フォルダにindex.htmlファイルを作成し、 'js'というフォルダを追加します。フォルダ 'js'にsocket.ioを追加します。クライアント側のjsは、'/home/pi/server/node_modules/socket.io/node_modules/socket.io-client/'というフォルダにあります。

はこのようにあなたのindex.htmlにクライアント側のためのsocket.io.jsを含める:

<script type="text/javascript" src="js/socket.io.js" /></script> 

はまた、あなたがしてあなたのjavascriptのコードを配置します「のjsの」フォルダにmain.jsファイルを追加し、それを含めますindex.htmlをに:

<script type="text/javascript" src="js/main.js" /></script> 
<script type="text/javascript" src="js/jquery.js" /></script> 

私はのための任意のグラフィックスをすることはありませんが、いくつかのmain.jsコードはここにある:

$(document).ready(function() { 
    var socket = io.connect('http://your_ip_address_rpi:3000'); 

    $("#myButton").click(function(){ 
     io.emit("WriteSerial:get", $("#myTextHolder").val()); //"FAAF531C" this is string of hex, should be added some filter to pass error when char is not part of HEX! 
    }); 
    $("#myButton2").click(function(){ 
     io.emit("WriteGPIO:get", {"pin" : $("#myPinHolder").val(), "time" : $("#myTimeHolder").val()}) 

} 

RPI起動時にサーバーを実行するには、 'sudo node /home/pi/server/server.js &'を '/etc/rc.local'に 'exit 0'の前に 'sudo nano'エディタで追加します。

これはどんなデバイスでもうまく動作します。

+0

ありがとうございます。私はnode.jsを使ったことはありませんが、試してみることができます。それは私の元のコードはしない間に私の携帯電話で動作するように別に何をするかを精緻化することはできますか? – CrimsonKnights

+0

私はそれをテストし、私が試したすべてのモバイルデバイスで動作します。ノードのパフォーマンスが向上し、Web要求と応答を処理するためのライブラリが組み込まれているため、別のWebサーバーやその他の依存関係は必要ありません。私たちがラズベリー・パイ・ノードについて語っているように、RPIの安定性は維持されます。 PHPはノードと比較して "使いやすい"ものですが、この状態ではノードを推奨します。 – Avoid

+0

自分自身で多くのノードサーバーを作りました。私は個人的にはPHPよりもノードを好みます。 – Avoid

関連する問題