提供一個interface上通過腳本擴展短鏈接第三方登錄的例子(kbengine)

這是一個interface上通過腳本擴展短鏈接第三方登錄的例子,這個類可以看成是一個poller,每一個登陸請求可以創建一個這樣的poller,也可以在外部設計一個回收池來回收。完全看你自己想要怎麼管理。
初始化以後使用start方法來連接並通過socket模擬http發送消息,發送完畢之後會等待接受返回。示例中通過解析json串來得到返回信息,用戶可以根據自己的需要修改成其他的方式。

這個示例中通過使用向底層註冊fd的方式實現了異步發送和異步接收。

可能的問題:該示例中connet這一步依然是阻塞的,在極限情況下可能存在性能問題。

 

 

# -*- coding: utf-8 -*-
import KBEngine
import Functor
import socket
from KBEDebug import *
import json

class LoginPoller:
	def __init__(self, _callback, _host, _page, _port, _overtime = 5):
		"""
		@param _callback: 數據處理完畢之後調用的外部回調, 注意不可在外部回調中銷燬這個LoginPoller自己
		@param _host: 主機地址, 可以是域名也可以是ip地址
		@param _page: 請求頁面
		@param _port: 請求端口
		@param _overtime: 超時秒數
		"""
		self._socket = None
		self._request_str = ""
		self._recv_str = ""
		self._recv_data = {}
		self._callback = _callback
		self._host = _host
		self._page = _page
		self._port = _port
		self._overtime = _overtime
		self._registerRead = False
		self._registerWrite = False
		
	def start(self, _commitName, _realAccountName, _datas, _param_data, _tid):
		"""
		@param _commitName, _realAccountName, _datas: 這三個參數來自於requestAccountLogin,記在這個LoginPoller中,
		數據請求完畢之後可以從外部重新拿到這些數據
		@param _param_data: http請求參數
		@param _tid: 可視爲這個LoginPoller的Id, 回調時會返回這個id, 便於外部管理
		"""
		self._commitName = _commitName
		self._realAccountName = _realAccountName
		self._datas = _datas
		self._tid = _tid

		self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		DEBUG_MSG("self._host: %s, self._port: %d" % (self._host, self._port))
		self._socket.connect((self._host, self._port))

		self.registerRead()

		_rstr = "GET " + self._page + "?" + _param_data + " HTTP/1.1\r\n"
		_rstr += "Host: %s\r\n" % self._host
		_rstr += "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:43.0) Gecko/20100101 Firefox/43.0\r\n"
		_rstr += "Connection: close\r\n"
		_rstr += "\r\n"
		self._request_str = _rstr.encode()
		_sendAll = self.send()

		if _sendAll != True:
			self.registerWrite()

	def stop(self):
		self.deregisterRead()
		self.deregisterWrite()
		if self._socket != None:
			self._socket.close()
			self._socket = None

	def send(self):
		_send_lenth = self._socket.send(self._request_str)
		self._request_str = self._request_str[_send_lenth:]

		if len(self._request_str) == 0:
			return True
		else:
			return False

	def checkValidity(self):
		# 檢查有效性, 超時檢查
		if self._overtime > 0 and self._socket != None:
			self._overtime -= 1
			return True
		else:
			return False

	def onWrite(self, fileno):
		_sendAll = self.send()

		if _sendAll == True:
			self.deregisterWrite()

	def onRecv(self, fileno):
		_data = self._socket.recv(2048)
		DEBUG_MSG("onRecv: %s" % _data)
		if self.checkRecv(_data) == True:
			self.processData()
			self.stop()
			self._callback(self._tid)

	def checkRecv(self, _data):
		self._recv_str += _data.decode()
		DEBUG_MSG("checkRecv: %s" % self._recv_str)
		_count1 = self._recv_str.count('{')
		_count2 = self._recv_str.count('}')
		if _count1 == _count2 and _count1 > 0:
			return True

		return False

	def processData(self):
		"""
		處理接收數據
		從接收數據中截取json串並解析
		"""
		_index1 = self._recv_str.find('{')
		_index2 = self._recv_str.rfind('}')

		_bodyStr = self._recv_str[_index1: _index2 + 1]
		DEBUG_MSG("_bodyStr: %s" % _bodyStr)
		self._recv_data = json.loads(_bodyStr)
		DEBUG_MSG("self._recv_data: %s" % str(self._recv_data))

	def getPollerInfos(self):
		return self._commitName, self._realAccountName, self._datas, self._recv_data

	def registerRead(self):
		if self._registerRead == False:
			KBEngine.registerReadFileDescriptor(self._socket.fileno(), self.onRecv)
			self._registerRead = True

	def registerWrite(self):
		if self._registerWrite == False:
			KBEngine.registerWriteFileDescriptor(self._socket.fileno(), self.onWrite)
			self._registerWrite = True

	def deregisterRead(self):
		if self._registerRead == True:
			KBEngine.deregisterReadFileDescriptor(self._socket.fileno())
			self._registerRead = False

	def deregisterWrite(self):
		if self._registerWrite == True:
			KBEngine.deregisterWriteFileDescriptor(self._socket.fileno())
			self._registerWrite = False

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章