Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/115.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django:JSON通知使用Redis PubSub、Node.js&;Socket.io_Python_Ios_Django_Json_Node.js - Fatal编程技术网

Python Django:JSON通知使用Redis PubSub、Node.js&;Socket.io

Python Django:JSON通知使用Redis PubSub、Node.js&;Socket.io,python,ios,django,json,node.js,Python,Ios,Django,Json,Node.js,我看到这篇文章: 这把我引向了正确的方向 我目前有一个iOS前端和一个Django后端。我使用Gunicorn向前端应用程序提供数据。我的iOS应用程序和我的备份应用程序之间的通信是基于REST的。我只是来回发送JSON。我不提供任何网页。只是JSON响应 我实现了一个简单的Post&Comment模型: class Post(models.Model): user = models.ForeignKey(User) blog = models.CharFie

我看到这篇文章:

这把我引向了正确的方向

我目前有一个iOS前端和一个Django后端。我使用Gunicorn向前端应用程序提供数据。我的iOS应用程序和我的备份应用程序之间的通信是基于REST的。我只是来回发送JSON。我不提供任何网页。只是JSON响应

我实现了一个简单的Post&Comment模型:

class Post(models.Model):
         user = models.ForeignKey(User)
         blog = models.CharField(max_length=5000)

class Comment(models.Model):
         comment = models.CharField(max_length=140)
         user = models.ForeignKey(User)
         post_id = models.ForeignKey(Post)
         created_at = models.DateTimeField(auto_now_add=True)
用户可以发表博客文章,其他用户也可以发表评论。所以如果userX有一篇博文和userY的评论。我想通知userX,userY对他/她的帖子发表了评论

我过去依靠通知用户;使用Twisted向APN发送通知的python包装器,但如果userX关闭我的应用的推送通知,则userX将无法接收应用内通知。所以我运气不好

我只关心应用程序内通知。我仍然希望userX在应用程序中时接收实时更新

当用户发出POST请求时,Django可以将消息发布到Redis上的频道。Node.js将订阅该频道,socket.io将其发送给该特定用户

下面是my views.py的精简版本,其中创建了注释对象。我将id发送给发表评论的用户、帖子的id以及发表博客帖子的用户的id。用户将使用json对此url发出post请求:

Node.js实现(根据上面Max Burstein的文章)


就我所知:(我知道这很令人伤心,但我还有很多问题。我如何才能订阅node.js到我从Django发布到的远程Redis服务器?有多少客户端可以连接到此套接字?是否有限制?是否为每个客户端创建了一个套接字?或者是否每个客户端都在同一个套接字上侦听?我是否可以通过此套接字将json数据发送到一个特定的客户端fic客户?我知道这是一个巨大的帖子,但我需要绝望的帮助。如果我不清楚什么,请告诉我,这样我就可以编辑这个问题。谢谢!

看看这里的实现:

听起来您应该使用类似RabbitMQ的东西,有node.js实现等等


看看吧,它应该会让你高兴起来:)

我绝对不会使用node.js来做这件事。你可以用Python处理WebSocket,用芹菜或gevent或其他任何东西

只需创建一个线程,注册到Redis并侦听新消息

当用户连接时,将套接字放入由用户名索引的弱值散列中;当他们的消息到达时,在该散列中查找目标用户名并将其发送。弱值是因为当用户断开连接时,它会自动清理。非常简单


我还使用websocket而不是HTTP-PUT向服务器发送新消息。

我还使用了一个很棒的库,名为django websocket redis

虽然它不使用gunicorn,但它使用uWSGI,这在迁移到时不会有太多开销。只需遵循文档,它们非常全面

使用django websockets redis实现部分代码:

## Make a json representation of your model available.

class Comment(models.Model):
     comment = models.CharField(max_length=140)
     user = models.ForeignKey(User)
     post_id = models.ForeignKey(Post)
     created_at = models.DateTimeField(auto_now_add=True)

    def as_json(self):
        return dict(
        id=self.id,
        comment=self.comment,
        created_at=self.created_at.strftime('%m/%d/%Y'),
        post_id=self.post_id
        user=self.user
        )
然后,在您的视图中,在发出请求时,将一个json表示保存到您订阅的redis工具中……您可以在任何地方执行此操作,不管是序列化程序还是视图,但这将由您决定

def UploadComment(request):
     data  = json.loads(request.body)

     ## In django-websockets-redis, this portion below is registered in the settings.py file, therefore i am commenting this out. 
     ## redis_server = redis.Redis(host='12.345.678.9', port=6379, db=0, password='mypassword')

     newComment = Comment()
     newComment.comment = data['comment']
     newComment.user_id = data['user_id']
     newComment.post_id = data['post_id']
     newComment.save() 
     PostOwner = data['post_owner_id'] #id of the blog post owner
     # Need to send a notification to PostOwner

     ## Need to turn this into a string before posting to redis
     json_comment = str(newComment.as_json())

     ## Create a facility based on the PostOwner ID. The PostOwner will always be subscribed to this channel. 
     RedisPublisher(facility=PostOwner, broadcast=True).publish_message(json_comment)

     return HttpResponse('Request Successful')
现在我们已经处理好了后端,在前端visa vie JavaScript上,您的用户根据其user.id向设施订阅:

jQuery(document).ready(function($) {
    var ws4redis = WS4Redis({
    uri: '{{ WEBSOCKET_URI }}{{ PostOwner.id }}?subscribe-broadcast&publish-broadcast&echo',
    receive_message: receiveMessage,
    heartbeat_msg: {{ WS4REDIS_HEARTBEAT }}
});

// receive a message though the Websocket from the server
function receiveMessage(msg) {
    //This is where you would retrieve the JSON string from the Redis server, and subsequently manipulate the DOM with appends, Toastr Notifications, Etc...
}

这篇文章的
node.js
实现比你在这里展示的要多得多。那么其余的部分对你不起作用了吗?你被锁定到node.js了吗?我已经实现了类似于python+celery+websockets的东西。你想继续使用sockets和node.js吗?还是你更愿意接受
redis(pub/sub)+gunicorn+SSE(服务器发送事件)
?@AamirAdnan SSE with Redis pub sub是另一种解决方案。但问题是,我知道具体发送给哪个客户端吗?只有特定客户端才会收到与他们相关的通知。有点像你的Instagram活动订阅源。每当有人评论或喜欢你的照片时,你都会在浏览器或mo中收到通知胆汁设备。每个用户都有自己的频道,他们都订阅了该频道。当用户A对用户B活动执行操作时,您将在用户B频道上发送通知。识别频道有什么困难吗?嘿@matthias urliches。刚刚偶然发现了您的答案,看起来与我非常相关-您能详细说明我如何创建这个k吗使用django/Cellery/other的线程索引?请提供至少链接到在这种情况下使用RabbitMQ的示例。仅提及它并提供指向devtools页面的链接只会打开更多的可能性,而不是进一步帮助他。。。
def UploadComment(request):
     data  = json.loads(request.body)

     ## In django-websockets-redis, this portion below is registered in the settings.py file, therefore i am commenting this out. 
     ## redis_server = redis.Redis(host='12.345.678.9', port=6379, db=0, password='mypassword')

     newComment = Comment()
     newComment.comment = data['comment']
     newComment.user_id = data['user_id']
     newComment.post_id = data['post_id']
     newComment.save() 
     PostOwner = data['post_owner_id'] #id of the blog post owner
     # Need to send a notification to PostOwner

     ## Need to turn this into a string before posting to redis
     json_comment = str(newComment.as_json())

     ## Create a facility based on the PostOwner ID. The PostOwner will always be subscribed to this channel. 
     RedisPublisher(facility=PostOwner, broadcast=True).publish_message(json_comment)

     return HttpResponse('Request Successful')
jQuery(document).ready(function($) {
    var ws4redis = WS4Redis({
    uri: '{{ WEBSOCKET_URI }}{{ PostOwner.id }}?subscribe-broadcast&publish-broadcast&echo',
    receive_message: receiveMessage,
    heartbeat_msg: {{ WS4REDIS_HEARTBEAT }}
});

// receive a message though the Websocket from the server
function receiveMessage(msg) {
    //This is where you would retrieve the JSON string from the Redis server, and subsequently manipulate the DOM with appends, Toastr Notifications, Etc...
}