Node.js与ZeroMQ + Socket.io +每个客户端的范围

时间:2012-04-08 16:42:19

标签: node.js socket.io zeromq

我正在使用node.js&编写一个Web应用程序。表达通过ZeroMQ&提供给每个用户的实时aprs流。 socket.io。

概念是:node.js应用程序具有通过订阅ZeroMQ发布者发送给它的完整aprs流。当用户访问网页(这是一个全屏地图)时,会设置一个socket.io会话,并将地图当前可见区域的边界发送回服务器。然后,服务器可以将完整的Feed作为范围,仅将地图上的新点发送给用户。

大多数都运行良好,但是当多个人加载网站时它会中断。当前查看的地图的范围变为全局,如果您缩放/平移一个地图,它将开始在两个浏览器的新位置上显示点。

我需要每个socket.io会话保留自己的范围,只接收来自其唯一作用域地图边界的数据,并且对每个访问者都是唯一的。我已经尝试在socket.io连接中嵌套zmqsocket.on "message", (data) ->回调,但它仍会产生相同的结果(即使在正确的回调中声明了mapbounds变量。)

可以在此处找到该应用程序的完整源代码:https://github.com/gmcintire/aprs.bz

如果您想在本地测试该应用,您应该能够克隆我的存储库,运行npm install,然后coffee app.coffee开始。请注意,它将从我的ZeroMQ服务器开始流式传输完整的APRS,这可能是~100KBytes / sec。

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

2 个答案:

答案 0 :(得分:1)

我不是CS或ZMQ的人,但听起来你是在向太多客户广播数据。 io.sockets.emit会将事件发送到所有连接的套接字。如果要将数据仅发送到1个套接字,则应使用socket.emit,其中socket已设置为单个套接字对象。

答案 1 :(得分: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");

或使用集合将每个套接字映射到其相关变量