3

node.jsとexpressを使用して、 ZeroMQとsocket.ioを介して各ユーザーにリアルタイムのaprsストリームを提供するWebアプリケーションを作成しています。

コンセプトは次のとおりです。node.jsアプリには、ZeroMQパブリッシャーにサブスクライブすることで完全なaprsストリームが送信されます。ユーザーがWebページ(フルスクリーンマップ)にアクセスすると、socket.ioセッションが設定され、マップの現在の表示領域の境界がサーバーに返送されます。その後、サーバーは完全なフィードのスコープを設定して、マップ上にある新しいスポットのみをユーザーに送信できます。

ほとんどは正常に機能していますが、複数の人がサイトをロードすると機能しなくなります。現在表示されているマップのスコープがグローバルになり、1つのマップをズーム/パンすると、新しい場所のスポットが両方のブラウザに表示され始めます。

各socket.ioセッションは、独自のスコープを保持し、一意のスコープマップ境界からのみデータを受信し、各訪問者に一意である必要があります。socket.io接続内にコールバックをネストしようとしましzmqsocket.on "message", (data) ->たが、それでも同じ結果が生成されます(適切なコールバック内で宣言されたmapbounds変数を使用しても)。

アプリケーションの完全なソースはここにあります:https ://github.com/gmcintire/aprs.bz

npm installアプリをローカルでテストする場合は、リポジトリのクローンを作成し、実行しcoffee app.coffeeてから開始できるはずです。ZeroMQサーバーから完全なAPRSフィードのストリーミングを開始することに注意してください。これは約100Kバイト/秒になる可能性があります。

app.coffee

express = require("express")
routes = require("./routes")
geolib = require("geolib")
zmq = require("zmq")
zmqsocket = zmq.socket("sub")

zmqsocket.connect "tcp://stream.aprs.bz:12777"
zmqsocket.subscribe ""
app = module.exports = express.createServer()
io = require("socket.io").listen(app)

mapbounds = ""

io.sockets.on "connection", (socket) ->
  #console.log socket
  socket.on "mapmove", (mapcoords) ->
    console.log mapbounds
    mapbounds = mapcoords

zmqsocket.on "message", (data) ->
  packet = JSON.parse(data)
  #console.log packet

  if packet.latitude? and packet.longitude? and (mapbounds != "")
    insideMap = geolib.isPointInside
      latitude: packet.latitude
      longitude: packet.longitude
    , [
      latitude: mapbounds._northEast.lat
      longitude: mapbounds._southWest.lng
    ,
      latitude: mapbounds._northEast.lat
      longitude: mapbounds._northEast.lng
    ,
      latitude: mapbounds._southWest.lat
      longitude: mapbounds._northEast.lng
    ,
      latitude: mapbounds._southWest.lat
      longitude: mapbounds._southWest.lng
    ]
    if insideMap
      console.log "\n--------------------------------------------------------\n"
      io.sockets.emit "packet", packet
      console.log packet

app.configure ->
  app.set "views", __dirname + "/views"
  app.set "view engine", "jade"
  app.use express.bodyParser()
  app.use express.methodOverride()
  app.use app.router
  app.use express.static(__dirname + "/public")

app.configure "development", ->
  app.use express.errorHandler(
    dumpExceptions: true
    showStack: true
  )

app.configure "production", ->
  app.use express.errorHandler()

app.get "/", routes.index
if app.settings.env == "development"
  app.listen 3000
else
  app.listen 80

console.log "Express server listening on port %d in %s mode", app.address().port, app.settings.env
4

2 に答える 2

1

私もCSでもZMQでもありませんが、あまりにも多くのクライアントにデータをブロードキャストしているようです。io.sockets.emit接続されているすべてのソケットにイベントを発行します。1つのソケットのみにデータを送信する場合は、単一のソケットオブジェクトに設定されているsocket.emit場所を使用する必要があります。socket

于 2012-04-09T16:03:49.963 に答える
0

私はCoffeeの経験はありませんが、変数をグローバルに保存していることがわかります。

var mapboudns = 10
io.sockets.on('connection', function(socket){
    socket.on("msg", function(data){
      mapbounds = data.bounds; //new value of mapbounds is altered globally
    });
});

次のようなものを使用してみてください:

socket.set("mapbounds", someNewValue);

後で値を取得するには:

socket.get("mapbounds");

または、コレクションを使用して、各ソケットを関連する変数にマップします

于 2012-04-09T15:20:49.303 に答える