mirror of
https://github.com/django/daphne.git
synced 2025-07-10 16:02:18 +03:00
Keepalive messages for WebSockets, and ! response chan prefix
This commit is contained in:
parent
804a4c561e
commit
b5210e38c4
|
@ -1,9 +1,11 @@
|
||||||
import django
|
import django
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
|
|
||||||
from channels import Channel, channel_backends, DEFAULT_CHANNEL_BACKEND
|
from channels import Channel, channel_backends, DEFAULT_CHANNEL_BACKEND
|
||||||
from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory
|
|
||||||
|
|
||||||
|
|
||||||
class InterfaceProtocol(WebSocketServerProtocol):
|
class InterfaceProtocol(WebSocketServerProtocol):
|
||||||
|
@ -20,7 +22,8 @@ class InterfaceProtocol(WebSocketServerProtocol):
|
||||||
|
|
||||||
def onOpen(self):
|
def onOpen(self):
|
||||||
# Make sending channel
|
# Make sending channel
|
||||||
self.send_channel = Channel.new_name("django.websocket.send")
|
self.send_channel = Channel.new_name("!django.websocket.send")
|
||||||
|
self.last_keepalive = time.time()
|
||||||
self.factory.protocols[self.send_channel] = self
|
self.factory.protocols[self.send_channel] = self
|
||||||
# Send news that this channel is open
|
# Send news that this channel is open
|
||||||
Channel("django.websocket.connect").send(
|
Channel("django.websocket.connect").send(
|
||||||
|
@ -67,6 +70,16 @@ class InterfaceProtocol(WebSocketServerProtocol):
|
||||||
**self.request_info
|
**self.request_info
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def sendKeepalive(self):
|
||||||
|
"""
|
||||||
|
Sends a keepalive packet on the keepalive channel.
|
||||||
|
"""
|
||||||
|
Channel("django.websocket.keepalive").send(
|
||||||
|
send_channel = self.send_channel,
|
||||||
|
**self.request_info
|
||||||
|
)
|
||||||
|
self.last_keepalive = time.time()
|
||||||
|
|
||||||
|
|
||||||
class InterfaceFactory(WebSocketServerFactory):
|
class InterfaceFactory(WebSocketServerFactory):
|
||||||
"""
|
"""
|
||||||
|
@ -106,6 +119,7 @@ class WebsocketTwistedInterface(object):
|
||||||
self.factory.protocol = InterfaceProtocol
|
self.factory.protocol = InterfaceProtocol
|
||||||
reactor.listenTCP(self.port, self.factory)
|
reactor.listenTCP(self.port, self.factory)
|
||||||
reactor.callInThread(self.backend_reader)
|
reactor.callInThread(self.backend_reader)
|
||||||
|
reactor.callLater(1, self.keepalive_sender)
|
||||||
reactor.run()
|
reactor.run()
|
||||||
|
|
||||||
def backend_reader(self):
|
def backend_reader(self):
|
||||||
|
@ -130,3 +144,14 @@ class WebsocketTwistedInterface(object):
|
||||||
continue
|
continue
|
||||||
# Deal with the message
|
# Deal with the message
|
||||||
self.factory.dispatch_send(channel, message)
|
self.factory.dispatch_send(channel, message)
|
||||||
|
|
||||||
|
def keepalive_sender(self):
|
||||||
|
"""
|
||||||
|
Sends keepalive messages for open WebSockets every
|
||||||
|
(channel_backend expiry / 2) seconds.
|
||||||
|
"""
|
||||||
|
expiry_window = int(self.channel_backend.expiry / 2)
|
||||||
|
for protocol in self.factory.protocols.values():
|
||||||
|
if time.time() - protocol.last_keepalive > expiry_window:
|
||||||
|
protocol.sendKeepalive()
|
||||||
|
reactor.callLater(1, self.keepalive_sender)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user