提供一个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
发布了13 篇原创文章 · 获赞 0 · 访问量 2298

猜你喜欢

转载自blog.csdn.net/kbengine/article/details/104882613
今日推荐