aardio的jsonRpc服务端是比较简单好用的,在项目上线的过程中发现会有被人扫描端口收到乱码请求的情况,导致jsonRpc服务端RAW错误而崩溃,比如这样的:
---------------------------
RAW CALLBACK ERROR
---------------------------
{File}:~lib\win\ui\_.aardio
{Line}:#291
{Error}:
{File}:~lib\web\socket\server.aardio
{Line}:#204
{Error}:
{Calling}:'push'
{Bad argument}:@1
'
{Expected}:table
{Got}:buffer'
---------------------------
确定
---------------------------
通过查看标准库web.socket.server的源代码,发现client.cacheFragment.data预期为table,实际获取到buffer时会崩溃,是client.cacheFragment.data = buffer;这一句把它设置为buffer的.所以可以尝试的解决办法有以下.
第1种,添加一行,判断client.cacheFragment.data的类型是不是table,不是就返回
if(type(client.cacheFragment.data != "table")){return ; }
..table.push(client.cacheFragment.data,msg.data);
client.cacheFragment.length = client.cacheFragment.length + #(msg.data);
这种改法的好处是只需要重新发布服务端即可,不需要修改客户端升级.
第2种,要修改客户端,在客户端上添加一个请求头,然后在服务端上判断这个请求头,过滤掉非客户端发来的请求
//可以在客户端添加特定的请求头,也可以修改ua,然后服务端判断,不对就关闭返回
this.httpServer.onUpgradeProtocol = function(client,request,response){
//添加的这段,判断请求头里有没有特定的项,没有此项就说明不是客户端发来的,防止遇到别人扫描发来的请求造成错误
//import console;
//console.varDump(request.headers["client-from"])
//判断添加特定的请求头是否正确
if(request.headers["client-from"] != "jianma-soft-client"){
console.log("别扫描,不处理的")
response.errorStatus(400);
response.close(true);
return ;
}
然后客户端里添加请求头项:
//添加请求头项,让服务端识别,不处理别的扫描发来的无此请求头项的请求
ws.rpc.headers = {
["client-from"] = "jianma-soft-client";
}
这种改法的好处是通俗易懂,缺点是如果已经发布了客户端,则要重新发布升级客户端,有些已经上线的项目不好升级.
用示例中的服务端和客户端测试成功.