github上面的jsrpc是用go语言写的,需要自己编译成exe文件,虽然可以用功能也很强大
但还是想用python来实现。动手自己写一个很简单直接上代码了。简单功能实现了,够用了啊。
import asyncio
import websockets
import json
import threading
import time
class JSRPC():
def __init__(self,port=9000):
'''
运行服务器端
rpc=JSRPC(port=9000)
rpc.run_server()
time.sleep(10000)
运行客户端
rpc=JSRPC(port=9000)
rpc.run_client(name="cookie",data="hello")
即向浏览器发送 {'name': 'cookie', 'data': 'hello'}
浏览器如果没注册name则返回 {'data': '未注册action:cookie', 'code': False, 'name': None}
如果已注册则返回 {'data': 'helloooo....', 'code': True, 'name': 'cookie'}
浏览器注入js代码 建立通信
const socket = new WebSocket('ws://127.0.0.1:9000')//修改服务器端口号
socket.onerror = (e) => {console.error('rpc错误:', e)}
socket.onclose = (e) => {console.log('rpc已关闭', e)}
socket.onopen = function (e) {
message = {reg: 'cookie'}
console.log('发送:',message)
socket.send(JSON.stringify(message));
};
socket.onmessage = (e) => {
data = JSON.parse(e.data);
console.log('收到:', data)
websocket_id=data['websocket_id']
if (websocket_id){
message={'websocket_id':websocket_id}
/* 下面修改自己的代码赋值给 message['data'] */
message['data']="helloooo...."
/*----------------------------------------*/
console.log('发送:',message)
socket.send(JSON.stringify(message));
}
}
'''
self.port=port
self.conn = {}
self.loop = asyncio.new_event_loop()
def run_server(self):
import websockets
async def handle_client(websocket, url_path):
current_id = id(websocket)
#清理失效的连接
for _ in [k for k, v in self.conn.items() if not v[1].open]:
del self.conn[_]
async for message in websocket:
sent_data = {'data': '', 'code': True}
try:
recv_data = json.loads(message) # 消息数据
print(f"[ 收到 <-- {current_id} ] {recv_data}")
reg = recv_data.get('reg') # 注册名
name = recv_data.get('name') # 请求注册名
data = recv_data.get('data') # 获取数据
desc_id = recv_data.get('websocket_id') # 目标websocket id
recv_websocket = websocket
#如果是注册
if reg:
for websocket_id_, v in self.conn.items():
if reg == v[0]:
self.conn[current_id] = [reg, websocket]
del self.conn[websocket_id_]
print(f'[ 删除 {websocket_id_} ]')
break
else:
self.conn[current_id] = [reg, websocket]
sent_data['data'] = f'注册成功:{reg}'
#通过注册名找到websocket连接发送 py转发给浏览器消息
elif name:
for websocket_id_, v in self.conn.items():
if v[0] and name == v[0]:
recv_websocket = v[1]
sent_data['data'] = data
sent_data['websocket_id'] = current_id
self.conn[current_id] = [None, websocket]
break
else:
sent_data['name'] = None
sent_data['data'] = f'未注册action:{name}'
sent_data['code'] = False
#通过id找到websocket连接发送 浏览器转发给py消息
elif desc_id:
if desc_id in self.conn:
sent_data['data'] = data
sent_data['name'] = self.conn[current_id][0]
recv_websocket = self.conn[desc_id][1]
else:
sent_data['data'] = '目标连接已断开'
else:
sent_data['data'] = f'没有action参数'
sent_data['code'] = False
except json.JSONDecodeError as e:
sent_data['data'] = f'{e}'
print(f'[ 发送 --> {id(recv_websocket)} ] {sent_data}')
await recv_websocket.send(json.dumps(sent_data)) # 发送处理结果给客户端
print('-' * 100)
start_server = websockets.serve(handle_client, "127.0.0.1", self.port,loop=self.loop)
print(f'run at http://127.0.0.1:{self.port}')
print('*' * 100)
self.loop.run_until_complete(start_server)
self.loop.run_forever()
def run_server_thread(self):
th=threading.Thread(target=self.run_server)
th.start()
def run_client(self,name='cookie', data='你好'):
import websockets
try:
async def rpc(name, data):
try:
async with websockets.connect(f'ws://127.0.0.1:{self.port}') as websocket:
json_data = {'name': name, 'data': data}
await websocket.send(json.dumps(json_data)) # 发送消息
recv_msg = await websocket.recv()
return json.loads(recv_msg) # 接收消息
except Exception as e:
raise Exception(f'jsrpc错误:{e}')
return asyncio.get_event_loop().run_until_complete(rpc(name, data))
except Exception as e:
return {'code': False, 'data': None,'msg':f'{e}'}
rpc=JSRPC()
rpc.run_server_thread()
time.sleep(1)
while True:
data={'params':'a=1&b=你好'}
rpc.run_client(name='cookie',data=data)
input()
浏览器注入