2017-01-22 68 views
0

我的服務器設置爲每隔100毫秒打勾並更新所有客戶端 - 請參閱self.TICKS_PER_SECOND = 10,1000/10 = 100毫秒。爲什麼服務器每隔1秒更新客戶端而不是100毫秒 - 可用完整源代碼

然而,在HTML中的「時鐘」只得到更新每隔1秒。爲什麼?

如果我繼續單擊提交按鈕比時鐘得到更新更快。爲什麼?

app.py

import logging 
import sys 
from datetime import datetime 
import time 
current_milli_time = lambda: int(round(time.time() * 1000)) 

import json 
import threading 

from twisted.web.static import File 
from twisted.python import log 
from twisted.web.server import Site 
from twisted.web.resource import Resource 

from twisted.internet import pollreactor 
pollreactor.install() 

from twisted.internet import reactor 

from autobahn.twisted.websocket import WebSocketServerFactory, \ 
    WebSocketServerProtocol 

from autobahn.twisted.resource import WebSocketResource 


class AppGameServerProtocol(WebSocketServerProtocol): 

    def onOpen(self): 
     """ 
     """ 
     self.factory.register(self) 
     self.factory.onConnected(self) 

    def onConnect(self, request): 
     print("Client connecting: {}".format(request.peer)) 

    def connectionLost(self, reason): 
     self.factory.unregister(self) 

    def onMessage(self, payload, isBinary): 
     self.factory.communicate(self, payload, isBinary) 


class AppGameFactory(WebSocketServerFactory): 

    def __init__(self, *args, **kwargs): 
     super(AppGameFactory, self).__init__(*args, **kwargs) 
     self.clients = {} 

    def register(self, client): 
     self.clients[client.peer] = {"object": client, "partner": None} 

    def unregister(self, client): 
     self.clients.pop(client.peer) 


    def onConnected(self,client): 
     client.sendMessage(json.dumps({"type": "connect"})) 

    def communicate(self, client, payload, isBinary): 
     print "msg received", payload 

    def sendMessageAll(self, message): 
     for i in self.clients: 
      c = self.clients[i] 
      c["object"].sendMessage(message) 

class SummingThread(threading.Thread): 
    def __init__(self, fac): 
     super(SummingThread, self).__init__() 
     self.fac = fac 

     self.TICKS_PER_SECOND = 10 
     self.SKIP_TICKS = 1000/self.TICKS_PER_SECOND 
     self.MAX_FRAMESKIP = 5 
     self.loops = 0 
     self.next_game_tick = current_milli_time() 

    def run(self): 
     while True: 
      self.loops = 0 
      while current_milli_time() > self.next_game_tick and self.loops < self.MAX_FRAMESKIP: 

       self.fac.sendMessageAll("clock: " + datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]) 
       self.next_game_tick += self.SKIP_TICKS 
       self.loops += 1 



if __name__ == "__main__": 
    log.startLogging(sys.stdout) 

    factory = AppGameFactory(u"ws://127.0.0.1:8080") 
    factory.protocol = AppGameServerProtocol 
    resource = WebSocketResource(factory) 

    root = Resource() 
    root.putChild('', File('index.html')) 

    root.putChild(u"ws", resource) 

    thread1 = SummingThread(factory) 
    thread1.start() 

    try: 
     site = Site(root) 
     reactor.listenTCP(8080, site) 
     reactor.run() 
    except Exception as e: 
     logging.exception("message") 

的index.html

<!DOCTYPE html> 
<html> 
<head> 
    <script type="text/javascript"> 
     window.addEventListener("load", function() { 

      var msgReceived = 0 

      // create websocket instance 
      var mySocket = new WebSocket("ws://localhost:8080/ws"); 

      // add event listener reacting when message is received 
      mySocket.onmessage = function (event) { 
       var output = document.getElementById("output"); 
       // put text into our output div 
       msgReceived++; 
       output.textContent = event.data + " msgReceived: " + msgReceived; 
       //console.log(event.data); 
      }; 

      var form = document.getElementsByClassName("foo"); 
      var input = document.getElementById("input"); 

      form[0].addEventListener("submit", function (e) { 
       // on forms submission send input to our server 
       input_text = input.value; 
       mySocket.send(input_text); 
       e.preventDefault() 
      }) 
     }); 

    </script> 
<style> 
    /* just some super ugly css to make things bit more readable*/ 
    div { 
     margin: 2em; 
    } 
    form { 
     margin: 2em; 
    } 
</style> 
</head> 
<body> 
    <form class="foo"> 
     <input id="input"></input> 
     <input type="submit"></input> 
    </form> 
    <div id="output"></div> 
</body> 
</html> 

回答

0

你調用多個線程扭曲的API。這是不允許的。你可以只調用從反應器線程扭曲的API - 除了幾個特定線程安全的API。晴reactor.callFromThread該時間表功能在反應器線程中運行。

考慮使用基於twisted.internet.task.LoopingCall的結構替換SummingThread

例如:

from twisted.internet.task import LoopingCall 

def game_tick(factory, skip_count): 
    now = datetime.utcnow() 
    factory.sendMessageAll(
     "clock: " + now.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3] 
    ) 


factory = # ... 
task = LoopingCall.withCount(partial(game_tick, factory)) 
task.start(0.1) 
# ... 
reactor.run() 

game_tick將被稱爲每秒10次(或者,如果不經常因爲負荷過高或其他一些問題,skip_count將被設置大於一,表示有多少蜱被遺漏)。

相關問題