mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
support connectHttp
This commit is contained in:
parent
5f859b3901
commit
ebc6b3f7d0
@ -8,7 +8,6 @@ import Task
|
|||||||
import DirectNotifyGlobal
|
import DirectNotifyGlobal
|
||||||
import ClientDistClass
|
import ClientDistClass
|
||||||
import CRCache
|
import CRCache
|
||||||
import Datagram
|
|
||||||
# The repository must import all known types of Distributed Objects
|
# The repository must import all known types of Distributed Objects
|
||||||
#import DistributedObject
|
#import DistributedObject
|
||||||
#import DistributedToon
|
#import DistributedToon
|
||||||
@ -26,6 +25,23 @@ class ClientRepository(DirectObject.DirectObject):
|
|||||||
self.doId2cdc={}
|
self.doId2cdc={}
|
||||||
self.parseDcFile(dcFileName)
|
self.parseDcFile(dcFileName)
|
||||||
self.cache=CRCache.CRCache()
|
self.cache=CRCache.CRCache()
|
||||||
|
|
||||||
|
# Set this true to establish a connection to the server using
|
||||||
|
# the HTTPClient interface, which ultimately uses the OpenSSL
|
||||||
|
# socket library (even though SSL is not involved). This is
|
||||||
|
# not as robust a socket library as NSPR's, but the HTTPClient
|
||||||
|
# interface does a good job of negotiating the connection over
|
||||||
|
# an HTTP proxy if one is in use.
|
||||||
|
|
||||||
|
# Set it false to use Panda's net interface
|
||||||
|
# (e.g. QueuedConnectionManager, etc.) to establish the
|
||||||
|
# connection, which ultimately uses the NSPR socket library.
|
||||||
|
# This is a much better socket library, but it may be more
|
||||||
|
# than you need for most applications; and the Panda net
|
||||||
|
# interface doesn't support proxies at all.
|
||||||
|
self.connectHttp = base.config.GetBool('connect-http', 1)
|
||||||
|
|
||||||
|
self.tcpConn = None
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def parseDcFile(self, dcFileName):
|
def parseDcFile(self, dcFileName):
|
||||||
@ -47,66 +63,64 @@ class ClientRepository(DirectObject.DirectObject):
|
|||||||
self.name2cdc[dcClass.getName()]=clientDistClass
|
self.name2cdc[dcClass.getName()]=clientDistClass
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def connect(self, serverName, serverPort):
|
def connect(self, serverURL,
|
||||||
self.qcm=QueuedConnectionManager()
|
successCallback = None, successArgs = [],
|
||||||
|
failureCallback = None, failureArgs = []):
|
||||||
|
"""
|
||||||
|
Attempts to establish a connection to the server. May return
|
||||||
|
before the connection is established. The two callbacks
|
||||||
|
represent the two functions to call (and their arguments) on
|
||||||
|
success or failure, respectively. The failure callback also
|
||||||
|
gets one additional parameter, which will be passed in first:
|
||||||
|
the return status code giving reason for failure, if it is
|
||||||
|
known.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if self.connectHttp:
|
||||||
|
ch = self.http.makeChannel(0)
|
||||||
|
ch.beginConnectTo(serverURL)
|
||||||
|
ch.spawnTask(name = 'connect-to-server',
|
||||||
|
callback = self.httpConnectCallback,
|
||||||
|
extraArgs = [ch, successCallback, successArgs,
|
||||||
|
failureCallback, failureArgs])
|
||||||
|
else:
|
||||||
|
self.qcm = QueuedConnectionManager()
|
||||||
gameServerTimeoutMs = base.config.GetInt("game-server-timeout-ms",
|
gameServerTimeoutMs = base.config.GetInt("game-server-timeout-ms",
|
||||||
20000)
|
20000)
|
||||||
# A big old 20 second timeout.
|
# A big old 20 second timeout.
|
||||||
self.tcpConn = self.qcm.openTCPClientConnection(
|
self.tcpConn = self.qcm.openTCPClientConnection(
|
||||||
serverName, serverPort, gameServerTimeoutMs)
|
serverURL.getServer(), serverURL.getPort(),
|
||||||
# Test for bad connection
|
gameServerTimeoutMs)
|
||||||
if self.tcpConn == None:
|
|
||||||
return None
|
if self.tcpConn:
|
||||||
else:
|
|
||||||
self.tcpConn.setNoDelay(1)
|
self.tcpConn.setNoDelay(1)
|
||||||
self.qcr=QueuedConnectionReader(self.qcm, 0)
|
self.qcr=QueuedConnectionReader(self.qcm, 0)
|
||||||
self.qcr.addConnection(self.tcpConn)
|
self.qcr.addConnection(self.tcpConn)
|
||||||
self.cw=ConnectionWriter(self.qcm, 0)
|
self.cw=ConnectionWriter(self.qcm, 0)
|
||||||
self.startReaderPollTask()
|
self.startReaderPollTask()
|
||||||
return self.tcpConn
|
if successCallback:
|
||||||
|
successCallback(*successArgs)
|
||||||
def startRawReaderPollTask(self):
|
|
||||||
# Stop any tasks we are running now
|
|
||||||
self.stopRawReaderPollTask()
|
|
||||||
self.stopReaderPollTask()
|
|
||||||
task = Task.Task(self.rawReaderPollUntilEmpty)
|
|
||||||
# Start with empty string
|
|
||||||
task.currentRawString = ""
|
|
||||||
taskMgr.add(task, "rawReaderPollTask", priority=self.TASK_PRIORITY)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def stopRawReaderPollTask(self):
|
|
||||||
taskMgr.remove("rawReaderPollTask")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def rawReaderPollUntilEmpty(self, task):
|
|
||||||
while self.rawReaderPollOnce():
|
|
||||||
pass
|
|
||||||
return Task.cont
|
|
||||||
|
|
||||||
def rawReaderPollOnce(self):
|
|
||||||
self.notify.debug("rawReaderPollOnce")
|
|
||||||
self.ensureValidConnection()
|
|
||||||
availGetVal = self.qcr.dataAvailable()
|
|
||||||
if availGetVal:
|
|
||||||
datagram = NetDatagram()
|
|
||||||
readRetVal = self.qcr.getData(datagram)
|
|
||||||
if readRetVal:
|
|
||||||
str = datagram.getMessage()
|
|
||||||
self.notify.debug("rawReaderPollOnce: found str: " + str)
|
|
||||||
self.handleRawString(str)
|
|
||||||
else:
|
else:
|
||||||
ClientRepository.notify.warning("getData returned false")
|
# Failed to connect.
|
||||||
return availGetVal
|
if failureCallback:
|
||||||
|
failureCallback(0, *failureArgs)
|
||||||
|
|
||||||
def handleRawString(self, str):
|
def httpConnectCallback(self, ch, successCallback, successArgs,
|
||||||
# This method is meant to be pure virtual, and any classes that
|
failureCallback, failureArgs):
|
||||||
# inherit from it need to make their own handleRawString method
|
if ch.isConnectionReady():
|
||||||
pass
|
self.tcpConn = ch.getConnection()
|
||||||
|
self.tcpConn.userManagesMemory = 1
|
||||||
|
self.startReaderPollTask()
|
||||||
|
if successCallback:
|
||||||
|
successCallback(*successArgs)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Failed to connect.
|
||||||
|
if failureCallback:
|
||||||
|
failureCallback(ch.getStatusCode(), *failureArgs)
|
||||||
|
|
||||||
def startReaderPollTask(self):
|
def startReaderPollTask(self):
|
||||||
# Stop any tasks we are running now
|
# Stop any tasks we are running now
|
||||||
self.stopRawReaderPollTask()
|
|
||||||
self.stopReaderPollTask()
|
self.stopReaderPollTask()
|
||||||
taskMgr.add(self.readerPollUntilEmpty, "readerPollTask",
|
taskMgr.add(self.readerPollUntilEmpty, "readerPollTask",
|
||||||
priority=self.TASK_PRIORITY)
|
priority=self.TASK_PRIORITY)
|
||||||
@ -122,25 +136,42 @@ class ClientRepository(DirectObject.DirectObject):
|
|||||||
return Task.cont
|
return Task.cont
|
||||||
|
|
||||||
def readerPollOnce(self):
|
def readerPollOnce(self):
|
||||||
self.ensureValidConnection()
|
if self.connectHttp:
|
||||||
availGetVal = self.qcr.dataAvailable()
|
datagram = Datagram()
|
||||||
if availGetVal:
|
if self.tcpConn.receiveDatagram(datagram):
|
||||||
# print "Client: Incoming message!"
|
|
||||||
datagram = NetDatagram()
|
|
||||||
readRetVal = self.qcr.getData(datagram)
|
|
||||||
if readRetVal:
|
|
||||||
self.handleDatagram(datagram)
|
self.handleDatagram(datagram)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# Unable to receive a datagram: did we lose the connection?
|
||||||
|
if self.tcpConn.isClosed():
|
||||||
|
self.tcpConn = None
|
||||||
|
self.loginFSM.request("noConnection")
|
||||||
|
return 0
|
||||||
|
|
||||||
else:
|
else:
|
||||||
ClientRepository.notify.warning("getData returned false")
|
self.ensureValidConnection()
|
||||||
return availGetVal
|
if self.qcr.dataAvailable():
|
||||||
|
datagram = NetDatagram()
|
||||||
|
if self.qcr.getData(datagram):
|
||||||
|
self.handleDatagram(datagram)
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
def ensureValidConnection(self):
|
def ensureValidConnection(self):
|
||||||
# Was the connection reset?
|
# Was the connection reset?
|
||||||
|
if self.connectHttp:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
if self.qcm.resetConnectionAvailable():
|
if self.qcm.resetConnectionAvailable():
|
||||||
resetConnectionPointer = PointerToConnection()
|
resetConnectionPointer = PointerToConnection()
|
||||||
if self.qcm.getResetConnection(resetConnectionPointer):
|
if self.qcm.getResetConnection(resetConnectionPointer):
|
||||||
self.qcm.closeConnection(resetConnectionPointer.p())
|
resetConn = resetConnectionPointer.p()
|
||||||
|
self.qcm.closeConnection(resetConn)
|
||||||
|
if self.tcpConn.this == resetConn.this:
|
||||||
|
self.tcpConn = None
|
||||||
self.loginFSM.request("noConnection")
|
self.loginFSM.request("noConnection")
|
||||||
|
else:
|
||||||
|
self.notify.warning("Lost unknown connection.")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def handleDatagram(self, datagram):
|
def handleDatagram(self, datagram):
|
||||||
@ -386,7 +417,7 @@ class ClientRepository(DirectObject.DirectObject):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def sendSetShardMsg(self, shardId):
|
def sendSetShardMsg(self, shardId):
|
||||||
datagram = Datagram.Datagram()
|
datagram = Datagram()
|
||||||
# Add message type
|
# Add message type
|
||||||
datagram.addUint16(CLIENT_SET_SHARD)
|
datagram.addUint16(CLIENT_SET_SHARD)
|
||||||
# Add shard id
|
# Add shard id
|
||||||
@ -396,7 +427,7 @@ class ClientRepository(DirectObject.DirectObject):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def sendSetZoneMsg(self, zoneId):
|
def sendSetZoneMsg(self, zoneId):
|
||||||
datagram = Datagram.Datagram()
|
datagram = Datagram()
|
||||||
# Add message type
|
# Add message type
|
||||||
datagram.addUint16(CLIENT_SET_ZONE)
|
datagram.addUint16(CLIENT_SET_ZONE)
|
||||||
# Add zone id
|
# Add zone id
|
||||||
@ -420,6 +451,14 @@ class ClientRepository(DirectObject.DirectObject):
|
|||||||
print "ClientRepository sending datagram:"
|
print "ClientRepository sending datagram:"
|
||||||
datagram.dumpHex(ostream)
|
datagram.dumpHex(ostream)
|
||||||
|
|
||||||
|
if not self.tcpConn:
|
||||||
|
self.notify.warning("Unable to send message after connection is closed.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.connectHttp:
|
||||||
|
if not self.tcpConn.sendDatagram(datagram):
|
||||||
|
self.notify.warning("Could not send datagram.")
|
||||||
|
else:
|
||||||
self.cw.send(datagram, self.tcpConn)
|
self.cw.send(datagram, self.tcpConn)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user