socket.io:在特定地理距离内向客户广播?

时间:2012-04-12 18:24:11

标签: geolocation coffeescript socket.io geospatial

“使用socket.io,我想将用户发送的消息仅广播到所有客户端的子集。子集将位于发出消息的用户的一定距离内(比如1km)。看来我需要添加这样的东西(http://stackoverflow.com/questions/27928/how-do-i-calculate-distance-between-two-latitude-longitude-points)到[socket.on'广播', (消息)]下面代码的部分(请注意这是coffeescript并从Shoaib Burq的geochat-example github repo(https://github.com/sabman/geochat-example)中提取)。“

现在包括里卡多的建议,用他的输入替换旧的[socket.on'广播',(消息) - >]部分(虽然我将“用户”更改为“记录”以与服务器的其余部分保持一致.coffee代码),最后是[find:]部分。但是有些问题,我不确定它是否与html代码或coffeescript的更新有关。再次感谢...

代码仍未运行。包括里卡多的最新建议:

 socket.on 'broadcast', (message) ->
    # find the sender and extract it's position
    Character.find { clientId: socket.id }, (record) =>
        chat_data =
            user: record
            conversation: message
        [lat, lng] = record.geometry.coordinates
        # find everyone within a 1km square
        km = 1/111
         area = 
            type: 'Polygon'
            coordinates: [
               [lat - km, lng - km]
               [lat + km, lng - km]
               [lat + km, lng + km]
               [lat - km, lng + km]
            ]
        Character.find { within: area }, (record) ->
            // send message to each user

     socket.broadcast.send JSON.stringify(chat_data)

我觉得“查找”部分可能存在问题。例如,里卡多写了

    console.log ">> find #{JSON.stringify(attrs)}"

但是在原始代码中,这用“=>”读取而不是“>>”:

    console.log "=> find #{JSON.stringify(attrs)}"

qs = require 'querystring'

find: (query, callback) ->
    console.log ">> find #{JSON.stringify(attrs)}"

    q = { operator: "or",  properties: attrs }
    url = lyr_config_characters.api_url
    key = lyr_config_characters.acl.get

    if query.id?
      url += "/#{attrs.id}?" + qs.stringify({ key })
    else if query.within?
      url += "/functions/within?" + qs.stringify({ key, input : query.within })
    else
      url += qs.stringify { key, input: q }

    req =
        method: "GET"
        uri: url
        headers: { "Content-Type": "application/json" }

    request req, (error, response, body) ->
        console.log error if error
        console.log "<< find #{body}"
        callback JSON.parse body ? '{}'

谢谢!

1 个答案:

答案 0 :(得分:0)

您使用的示例基于spatialdb,它似乎有非常不完整的文档。

从它的外观来看,你需要使用几何对象查询用户,它将返回包含在其中的点(用户):

socket.on 'broadcast', (message) ->
    # find the sender and extract it's position
    Character.find { clientId: socket.id }, (user) ->
        chat_data =
            user: user
            conversation: message
        [lat, lng] = user.geometry.coordinates
        # find everyone within a 1km square
        km = 1/111
        area = 
            type: 'Polygon'
            coordinates: [
               [lat - km, lng - km]
               [lat + km, lng - km]
               [lat + km, lng + km]
               [lat - km, lng + km]
            ]
        Character.find { within: area }, (users) ->
            // send message to each user

您还需要修改find方法以使用within查询:

find: (attrs, callback) ->
    console.log "=> find #{JSON.stringify(attrs)}"
    q = { operator: "or",  properties: attrs }
    if _.contains(_.keys(attrs), "id")
      url = "#{lyr_config_characters.api_url}/#{attrs.id}?key=#{lyr_config_characters.acl.get}"
    else if _.contains(_.keys(attrs), "within")
      url = "#{lyr_config_characters.api_url}/functions/within?key=#{lyr_config_characters.acl.get}&input=#{encodeURIComponent(JSON.stringify(attrs.within))}"
    else
      url = "#{lyr_config_characters.api_url}?key=#{lyr_config_characters.acl.get}&input=#{encodeURIComponent(JSON.stringify(q))}"
    req = { method: "GET", uri: url, headers: {"Content-Type": "application/json"} }

(为了理智,我会改写)

qs = require 'querystring'

find: (query, callback) ->
    console.log ">> find #{JSON.stringify(attrs)}"

    q = { operator: "or",  properties: attrs }
    url = lyr_config_characters.api_url
    key = lyr_config_characters.acl.get

    if query.id?
      url += "/#{attrs.id}?" + qs.stringify({ key })
    else if query.within?
      url += "/functions/within?" + qs.stringify({ key, input : query.within })
    else
      url += qs.stringify { key, input: q }

    req =
        method: "GET"
        uri: url
        headers: { "Content-Type": "application/json" }

    request req, (error, response, body) ->
        console.log error if error
        console.log "<< find #{body}"
        callback JSON.parse body ? '{}'