"使用 socket.io,我想将用户发送的消息仅广播到所有客户端的子集。子集将位于发出消息的用户的一定距离内(例如 1 公里)。似乎我需要将这样的东西(http://stackoverflow.com/questions/27928/how-do-i-calculate-distance-between-two-latitude-longitude-points)添加到下面代码的[socket.on 'broadcast',(消息)]部分(请注意,这是coffeescript,并从Shoaib Burq的geochat示例github存储库(https://github.com/sabman/geochat-example)中提取)。
现在包括里卡多的建议,用他的输入替换旧的[socket.on 'broadcast',(message)->]部分(尽管我将"user"更改为"record"以与server.coffee代码的其余部分保持一致),以及最后的[find:]部分。但是,有些问题,我不确定这是否与html代码或咖啡脚本的更新有关。再次提前感谢..
代码仍未运行。包括里卡多的最新建议:
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 ? '{}'
谢谢!
您使用的示例基于 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 ? '{}'