Ping clients and send position time modified by total lag between them
This commit is contained in:
parent
de83d5f47c
commit
7c2d7f4c7d
@ -32,6 +32,9 @@ class SyncClientProtocol(CommandProtocol):
|
|||||||
|
|
||||||
self.manager.update_global_state(paused, position, name)
|
self.manager.update_global_state(paused, position, name)
|
||||||
|
|
||||||
|
def handle_connected_ping(self, arg):
|
||||||
|
self.send_message('pong', arg)
|
||||||
|
|
||||||
def send_state(self, paused, position):
|
def send_state(self, paused, position):
|
||||||
self.send_message('state', ('paused' if paused else 'playing'), int(position*100))
|
self.send_message('state', ('paused' if paused else 'playing'), int(position*100))
|
||||||
|
|
||||||
@ -40,7 +43,7 @@ class SyncClientProtocol(CommandProtocol):
|
|||||||
connected = dict(
|
connected = dict(
|
||||||
state = 'handle_connected_state',
|
state = 'handle_connected_state',
|
||||||
seek = 'handle_connected_seek',
|
seek = 'handle_connected_seek',
|
||||||
#ping = 'handle_connected_ping',
|
ping = 'handle_connected_ping',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
initial_state = 'connected'
|
initial_state = 'connected'
|
||||||
@ -67,10 +70,14 @@ class Manager(object):
|
|||||||
|
|
||||||
self.global_paused = True
|
self.global_paused = True
|
||||||
self.global_position = 0.0
|
self.global_position = 0.0
|
||||||
|
self.last_global_update = 0.0
|
||||||
|
|
||||||
self.player_paused = True
|
self.player_paused = True
|
||||||
self.player_position = 0.0
|
self.player_position = 0.0
|
||||||
|
|
||||||
|
def get_current_global_position(self):
|
||||||
|
return self.global_position + (time.time() - self.last_global_update)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
factory = SyncClientFactory(self)
|
factory = SyncClientFactory(self)
|
||||||
reactor.connectTCP(self.host, self.port, factory)
|
reactor.connectTCP(self.host, self.port, factory)
|
||||||
@ -115,6 +122,16 @@ class Manager(object):
|
|||||||
|
|
||||||
def update_player_position(self, value):
|
def update_player_position(self, value):
|
||||||
self.player_position = value
|
self.player_position = value
|
||||||
|
#diff = self.get_current_global_position() - value
|
||||||
|
#if 0.2 <= abs(diff) <= 4:
|
||||||
|
# if diff > 0:
|
||||||
|
# diff -= 0.2
|
||||||
|
# else:
|
||||||
|
# diff += 0.2
|
||||||
|
# speed = (diff/4.0) + 1
|
||||||
|
# self.player.send_set_speed(speed)
|
||||||
|
#else:
|
||||||
|
# self.player.send_set_speed(1)
|
||||||
|
|
||||||
def update_player_paused(self, value):
|
def update_player_paused(self, value):
|
||||||
old = self.player_paused
|
old = self.player_paused
|
||||||
|
|||||||
@ -1,12 +1,19 @@
|
|||||||
#coding:utf8
|
#coding:utf8
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
import random
|
||||||
|
|
||||||
from twisted.internet.protocol import Factory
|
from twisted.internet.protocol import Factory
|
||||||
|
|
||||||
from .network_utils import CommandProtocol
|
from .network_utils import CommandProtocol
|
||||||
from .utils import parse_state
|
from .utils import parse_state
|
||||||
|
|
||||||
|
random.seed()
|
||||||
|
|
||||||
|
CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
|
||||||
|
|
||||||
|
def random_chars():
|
||||||
|
return ''.join(random.choice(CHARS) for _ in xrange(10))
|
||||||
|
|
||||||
class SyncServerProtocol(CommandProtocol):
|
class SyncServerProtocol(CommandProtocol):
|
||||||
def __init__(self, factory):
|
def __init__(self, factory):
|
||||||
@ -41,6 +48,9 @@ class SyncServerProtocol(CommandProtocol):
|
|||||||
|
|
||||||
self.factory.seek(self, position)
|
self.factory.seek(self, position)
|
||||||
|
|
||||||
|
def handle_connected_pong(self, arg):
|
||||||
|
self.factory.pong_received(self, arg)
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash('|'.join((
|
return hash('|'.join((
|
||||||
self.transport.getPeer().host,
|
self.transport.getPeer().host,
|
||||||
@ -62,7 +72,7 @@ class SyncServerProtocol(CommandProtocol):
|
|||||||
connected = dict(
|
connected = dict(
|
||||||
state = 'handle_connected_state',
|
state = 'handle_connected_state',
|
||||||
seek = 'handle_connected_seek',
|
seek = 'handle_connected_seek',
|
||||||
#ping = 'handle_connected_ping',
|
pong = 'handle_connected_pong',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
initial_state = 'init'
|
initial_state = 'init'
|
||||||
@ -78,7 +88,13 @@ class WatcherInfo(object):
|
|||||||
self.last_update = None
|
self.last_update = None
|
||||||
self.last_update_sent = None
|
self.last_update_sent = None
|
||||||
|
|
||||||
|
self.ping = None
|
||||||
|
self.last_ping_time = None
|
||||||
|
self.last_ping_value = None
|
||||||
|
|
||||||
def update_position(self, position):
|
def update_position(self, position):
|
||||||
|
if self.ping is not None:
|
||||||
|
position += self.ping
|
||||||
self.position = position
|
self.position = position
|
||||||
self.max_position = max(position, self.max_position)
|
self.max_position = max(position, self.max_position)
|
||||||
self.last_update = time.time()
|
self.last_update = time.time()
|
||||||
@ -150,10 +166,15 @@ class SyncFactory(Factory):
|
|||||||
position = self.find_position()
|
position = self.find_position()
|
||||||
if curtime is None:
|
if curtime is None:
|
||||||
curtime = time.time()
|
curtime = time.time()
|
||||||
|
|
||||||
|
if watcher.ping is not None:
|
||||||
|
position += watcher.ping
|
||||||
|
|
||||||
if self.pause_change_by:
|
if self.pause_change_by:
|
||||||
watcher.watcher_proto.send_state(self.paused, position, self.pause_change_by.name)
|
watcher.watcher_proto.send_state(self.paused, position, self.pause_change_by.name)
|
||||||
else:
|
else:
|
||||||
watcher.watcher_proto.send_state(self.paused, position, None)
|
watcher.watcher_proto.send_state(self.paused, position, None)
|
||||||
|
|
||||||
watcher.last_update_sent = curtime
|
watcher.last_update_sent = curtime
|
||||||
|
|
||||||
def find_position(self):
|
def find_position(self):
|
||||||
@ -168,3 +189,26 @@ class SyncFactory(Factory):
|
|||||||
#min() arg is an empty sequence
|
#min() arg is an empty sequence
|
||||||
return 0.0
|
return 0.0
|
||||||
|
|
||||||
|
def pong_received(self, watcher_proto, value):
|
||||||
|
watcher = self.watchers.get(watcher_proto)
|
||||||
|
if not watcher:
|
||||||
|
return
|
||||||
|
|
||||||
|
if watcher.last_ping_value == value:
|
||||||
|
time = (time.time() - watcher.last_ping_time)/2
|
||||||
|
if watcher.ping is None:
|
||||||
|
watcher.ping = time
|
||||||
|
else:
|
||||||
|
watcher.ping = watcher.ping*0.6 + time*0.4
|
||||||
|
|
||||||
|
self.schedule_send_ping(watcher)
|
||||||
|
|
||||||
|
def send_ping(self, watcher):
|
||||||
|
chars = random_chars()
|
||||||
|
watcher.last_ping_time = time.time()
|
||||||
|
watcher.last_ping_value = chars
|
||||||
|
watcher.watcher_proto.send_ping(chars)
|
||||||
|
|
||||||
|
def schedule_send_ping(self, watcher, when=1):
|
||||||
|
reactor.callLater(when, self.send_ping, watcher)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user