0
点赞
收藏
分享

微信扫一扫

JSRPC的三种实现方式


RPC 为远程过程调用,本文通过在浏览器端(服务端)开启一个WebSocket服务,接收命令,执行浏览器网页的加密代码,得到密文。
CMD端(客户端)也开启一个WebSocket服务与浏览器端交互,通过标准输入把命令发送给浏览器执行。

RPC简单实现

原测试网站

有一个base64的加密函数,是我们要调用的函数。

function encrypt(message){
base64 = btoa(message);
console.log(base64);
return base64;
}
encrypt("abc");

浏览器本地替换:

通过浏览器的“保存并覆盖”本地替换功能,新增WebSocket通信客户端代码。

// test

function encrypt(message) {
base64 = btoa(message);
console.log(base64);
return base64;
}
encrypt("abc");

(function () {
var ws = new WebSocket("ws://127.0.0.1:5678")

ws.onmessage = function (evt) {
console.log("收到消息:" + evt.data);
if (evt.data == "exit") {
wx.close();
} else {
ws.send(encrypt(evt.data));
}
}
})()

JSRPC的三种实现方式_客户端

Python实现websocket客户端

import sys
import asyncio
import websockets

async def receive_message(websocket):
while True:
send_text = input("请输入要加密的字符串:")
if send_text == "exit":
print("退出!")
await websocket.send(send_text)
await websocket.close()
sys.exit()
else:
await websocket.send(send_text)
response_text =await websocket.recv()
print("\n加密结果:", response_text)

start_server = websockets.serve(receive_message, "127.0.0.1", 5678)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

最终效果:

JSRPC的三种实现方式_开发语言_02

JsRpc的封装:github.com/jxhczhl/JsRpc

项目地址:https://github.com/jxhczhl/JsRpc

开启服务

go run main.go

JSRPC的三种实现方式_客户端_03

浏览器替换JS

把JsEnv.js代码和一下代码替换。

// 注入环境后连接通信
var demo = new Hlclient("ws://127.0.0.1:12080/ws?group=zzz&name=hlg");

JSRPC的三种实现方式_javascript_04

执行

import requests

jscode = """
(function(){
console.log("test")
return "执行成功"
})()
"""

url = "http://localhost:12080/execjs"
data = {
"group": "zzz",
"name": "hlg",
"jscode":jscode
}
res = requests.post(url, data=data)
print(res.text)

JSRPC的三种实现方式_github_05



JSRPC的三种实现方式_客户端_06

无参获取值

前端注入:

// 注册一个方法 第一个参数hello为方法名,
// 第二个参数为函数,resolve里面的值是想要的值(发送到服务器的)
demo.regAction("hello", function (resolve) {
//这样每次调用就会返回“好困啊+随机整数”
var Js_sjz = "好困啊"+parseInt(Math.random()*1000);
resolve(Js_sjz);
})

请求​​http://localhost:12080/go?group=zzz&name=hlg&action=hello​​查看JS执行结果:

JSRPC的三种实现方式_ecmascript_07

带参获取值

//写一个传入字符串,返回base64值的接口(调用内置函数btoa)
demo.regAction("hello2", function (resolve,param) {
//这样添加了一个param参数,http接口带上它,这里就能获得
var base666 = btoa(param)
resolve(base666);
})

JSRPC的三种实现方式_ecmascript_08

带多个参获 并且使用post方式 取值

//假设有一个函数 需要传递两个参数
function hlg(User,Status){
return User+"说:"+Status;
}

demo.regAction("hello3", function (resolve,param) {
//这里还是param参数 param里面的key 是先这里写,但到时候传接口就必须对应的上
res=hlg(param["user"],param["status"])
resolve(res);
})

JSRPC的三种实现方式_ecmascript_09

sekiro

​​说明文档​​

构建

在Linux或者mac上,执行脚本 build_demo_server.sh,之后得到产出发布压缩包:sekiro-service-demo/target/sekiro-release-demo.zip

如果是windows,或者不想自己构建,可以在这里直接​​下载​​。

运行客户端:

JSRPC的三种实现方式_客户端_10

注入服务端代码

Sekiro代码:​​https://sekiro.virjar.com/sekiro-doc/assets/sekiro_web_client.js​​

function guid() {
function S4() {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}

return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
}

var client = new SekiroClient("ws://127.0.0.1:5620/business-demo/register?group=rpc-test&clientId=" + guid());

client.registerAction("encrypt", function(request, resolve, reject) {
resolve(encrypt(request["data"]));
})

这里SekiroClient是用来与客户端交互的类,第一个参数是WS链接,其中group是业务分组,clientId是分组中的客户端ID。
registerAction用来注册事件,这里是encrypt。
request用来获取客户端发送来的数据,resolve用来返回客户端数据,通过request和resolve事件数据传输交互。

执行

下图是触发rpc-test业务分组的encrypt事件,传输数据abc,返回abc的加密数据。

JSRPC的三种实现方式_开发语言_11

完整代码:

(function () {
var newElement = document.createElement("script");
newElement.setAttribute("type", "text/javascript");
newElement.setAttribute("src", "https://sekiro.virjar.com/sekiro-doc/assets/sekiro_web_client.js");
document.body.appendChild(newElement);

window.encrypt= encrypt // 设置成全局函数,避免未定义

function guid() {
function S4() {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}
return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
}

function startSekiro() {
var client = new SekiroClient("ws://127.0.0.1:5620/business-demo/register?group=rpc-test&clientId=" + guid());

client.registerAction("encrypt", function (request, resolve, reject) {
resolve(window.encrypt(request["data"]));
})
}

setTimeout(startSekiro, 2000) // 等待Document加载完成
})();

参考

​​https://github.com/jxhczhl/JsRpc​​​​https://github.com/virjar/sekiro​​


举报

相关推荐

0 条评论