sekiro部署及 js-rpc-demo


sekiro部署及 js-rpc-demo

1. sekiro服務端部署

運行啟動腳本:

  1. bin/sekiro.sh :mac or linux
  2. bin/sekiro.bat :windows

到此項目就運行成功了, 但是這不是 https 項目 js rpc 是通過 websocket進行調用的, 在https站點中, 不是 wss 鏈接 是不成功的,所以我們要配合 nginx 進行 搭建

2. nginx 搭建

nginx 采用docker 進行安裝

拉取 nginx 鏡像

docker pull nginx

使用 openssl 生成證書

  1. 安裝openssl
yum -y install openssl openssl-devel
  1. 生成ca秘鑰
openssl genrsa -out local.key 2048
  1. 生成ca證書請求
openssl req -new -key local.key -out local.csr
  1. 生成ca根證書
openssl x509 -req -in local.csr -extensions v3_ca -signkey local.key -out local.crt
  1. 根據CA證書創建server端證書
openssl genrsa -out my_server.key 2048 
openssl req -new -key my_server.key -out my_server.csr
openssl x509 -days 365 -req -in my_server.csr -extensions v3_req -CAkey local.key -CA local.crt -CAcreateserial -out my_server.crt

創建nginx掛載目錄

mkdir -p /nginx/config /nginx/config /nginx/logs /nginx/ssl
將剛才生成證書 `local.crt`, `local.key` 移動到 /nginx/ssl 目錄下

創建 nginx 配置文件

在 /nginx/config目錄下創建 nginx.conf 文件

events {
    worker_connections  1024;
}

http{
upstream sekiro_business_netty {
  # sekiro 項目 地址
  server 127.0.0.1:5620;
}

server {
        listen       4431 default  ssl;  #監聽4331端口
        keepalive_timeout 100;  #開啟keepalive 激活keepalive長連接,減少客戶端請求次數

        ssl_certificate      /ssl/local.crt;   #server端證書位置
        ssl_certificate_key  /ssl/local.key;   #server端私鑰位置

        ssl_session_cache    shared:SSL:10m;         #緩存session會話
        ssl_session_timeout  10m;                    # session會話    10分鍾過期

       ssl_ciphers  HIGH:!aNULL:!MD5;
       ssl_prefer_server_ciphers  on;

        server_name   test.com;
        charset utf-8;

        location /business-demo {    #后續獲取加密參數時候用到的路由

          gzip on;
          gzip_min_length 1k;
          gzip_buffers 4 16k;
          gzip_http_version 1.0;
          gzip_comp_level 2;
          gzip_types application/json text/plain application/x-javascript text/css application/xml;
          gzip_vary on;

          proxy_read_timeout      500;
          proxy_connect_timeout   300;
          proxy_redirect          off;

          proxy_http_version 1.1;
          proxy_set_header    Upgrade $http_upgrade;
          proxy_set_header    Host                $http_host;
          proxy_set_header    X-Real-IP           $remote_addr;
          proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
          proxy_set_header    X-Forwarded-Proto   $scheme;

          proxy_pass http://sekiro_business_netty;
        }
  
        location /register {      #后續頁面或者手機進行wss連接用到的路由
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "Upgrade";
          proxy_set_header X-Real-IP $remote_addr;
          proxy_pass http://sekiro_business_netty;
        }

        location / {
          client_max_body_size 0;

          proxy_read_timeout      300;
          proxy_connect_timeout   300;
          proxy_redirect          off;

          proxy_http_version 1.1;

          proxy_set_header    Host                $http_host;
          proxy_set_header    X-Real-IP           $remote_addr;
          proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
          proxy_set_header    X-Forwarded-Proto   $scheme;

          proxy_pass http://sekiro_business_netty;
        }
    }
}

啟動 nginx

docker run --detach --name nginx-test -p 4431:4431 -v /nginx/data:/usr/share/nginx/html:rw -v /nginx/config/nginx.conf:/etc/nginx/nginx.conf/:rw -v /nginx/logs:/var/log/nginx/:rw -v /nginx/ssl:/ssl/:rw -d nginx

3. JS RPC DEMO


function SekiroClient(wsURL) {
    this.wsURL = wsURL;
    this.handlers = {};
    this.socket = {};
    // check
    if (!wsURL) {
        throw new Error('wsURL can not be empty!!')
    }
    this.webSocketFactory = this.resolveWebSocketFactory();
    this.connect()
}
SekiroClient.prototype.resolveWebSocketFactory = function() {
    if (typeof window === 'object') {
        var theWebSocket = window.WebSocket ? window.WebSocket : window.MozWebSocket;
        return function(wsURL) {
            function WindowWebSocketWrapper(wsURL) {
                this.mSocket = new theWebSocket(wsURL);
            }
            WindowWebSocketWrapper.prototype.close = function() {
                this.mSocket.close();
            }
            ;
            WindowWebSocketWrapper.prototype.onmessage = function(onMessageFunction) {
                this.mSocket.onmessage = onMessageFunction;
            }
            ;
            WindowWebSocketWrapper.prototype.onopen = function(onOpenFunction) {
                this.mSocket.onopen = onOpenFunction;
            }
            ;
            WindowWebSocketWrapper.prototype.onclose = function(onCloseFunction) {
                this.mSocket.onclose = onCloseFunction;
            }
            ;
            WindowWebSocketWrapper.prototype.send = function(message) {
                this.mSocket.send(message);
            }
            ;
            return new WindowWebSocketWrapper(wsURL);
        }
    }
    if (typeof weex === 'object') {
        // this is weex env : https://weex.apache.org/zh/docs/modules/websockets.html
        try {
            console.log("test webSocket for weex");
            var ws = weex.requireModule('webSocket');
            console.log("find webSocket for weex:" + ws);
            return function(wsURL) {
                try {
                    ws.close();
                } catch (e) {}
                ws.WebSocket(wsURL, '');
                return ws;
            }
        } catch (e) {
            console.log(e);
            //ignore
        }
    }
    //TODO support ReactNative
    if (typeof WebSocket === 'object') {
        return function(wsURL) {
            return new theWebSocket(wsURL);
        }
    }
    throw new Error("the js environment do not support websocket");
}
;
SekiroClient.prototype.connect = function() {
    console.log('sekiro: begin of connect to wsURL: ' + this.wsURL);
    var _this = this;
    // if (this.socket && this.socket.readyState === 1) {
    //     this.socket.close();
    // }
    try {
        this.socket = this.webSocketFactory(this.wsURL);
    } catch (e) {
        console.log("sekiro: create connection failed,reconnect after 2s");
        setTimeout(function() {
            _this.connect()
        }, 2000)
    }
    this.socket.onmessage(function(event) {
        _this.handleSekiroRequest(event.data)
    });
    this.socket.onopen(function(event) {
        console.log('sekiro: open a sekiro client connection')
    });
    this.socket.onclose(function(event) {
        console.log('sekiro: disconnected ,reconnection after 2s');
        setTimeout(function() {
            _this.connect()
        }, 2000)
    });
}
;
SekiroClient.prototype.handleSekiroRequest = function(requestJson) {
    console.log("receive sekiro request: " + requestJson);
    var request = JSON.parse(requestJson);
    var seq = request['__sekiro_seq__'];
    if (!request['action']) {
        this.sendFailed(seq, 'need request param {action}');
        return
    }
    var action = request['action'];
    if (!this.handlers[action]) {
        this.sendFailed(seq, 'no action handler: ' + action + ' defined');
        return
    }
    var theHandler = this.handlers[action];
    var _this = this;
    try {
        theHandler(request, function(response) {
            try {
                _this.sendSuccess(seq, response)
            } catch (e) {
                _this.sendFailed(seq, "e:" + e);
            }
        }, function(errorMessage) {
            _this.sendFailed(seq, errorMessage)
        })
    } catch (e) {
        console.log("error: " + e);
        _this.sendFailed(seq, ":" + e);
    }
}
;
SekiroClient.prototype.sendSuccess = function(seq, response) {
    var responseJson;
    if (typeof response == 'string') {
        try {
            responseJson = JSON.parse(response);
        } catch (e) {
            responseJson = {};
            responseJson['data'] = response;
        }
    } else if (typeof response == 'object') {
        responseJson = response;
    } else {
        responseJson = {};
        responseJson['data'] = response;
    }
    if (Array.isArray(responseJson)) {
        responseJson = {
            data: responseJson,
            code: 0
        }
    }
    if (responseJson['code']) {
        responseJson['code'] = 0;
    } else if (responseJson['status']) {
        responseJson['status'] = 0;
    } else {
        responseJson['status'] = 0;
    }
    responseJson['__sekiro_seq__'] = seq;
    var responseText = JSON.stringify(responseJson);
    console.log("response :" + responseText);
    this.socket.send(responseText);
}
;
SekiroClient.prototype.sendFailed = function(seq, errorMessage) {
    if (typeof errorMessage != 'string') {
        errorMessage = JSON.stringify(errorMessage);
    }
    var responseJson = {};
    responseJson['message'] = errorMessage;
    responseJson['status'] = -1;
    responseJson['__sekiro_seq__'] = seq;
    var responseText = JSON.stringify(responseJson);
    console.log("sekiro: response :" + responseText);
    this.socket.send(responseText)
}
;
SekiroClient.prototype.registerAction = function(action, handler) {
    if (typeof action !== 'string') {
        throw new Error("an action must be string");
    }
    if (typeof handler !== 'function') {
        throw new Error("a handler must be function");
    }
    console.log("sekiro: register action: " + action);
    this.handlers[action] = handler;
    return this;
}
;

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


// group 為分組名稱(調用時需要用到)
// clientId 客戶端id
var client = new SekiroClient("wss://主機地址:4431/business-demo/register?group=xwgg&clientId=" + guid());

client.registerAction("get_sign", function(request, resolve, reject) {
    // 請求時 傳遞的參數
    var info = request['info']
    // 這里可以調用瀏覽器中的方法
    // var result = md5(info)
    var result = 'get_sign:' + info
    resolve(result)
})

  1. Python 調用 sekiro 進行 rpc
import requests

url = 'https://主機地址:4431/business-demo/invoke'

# group 分組名   action js中對於的注冊的函數  info 具體傳參
data = {"group": "xwgg", "action": "get_sign", "info": "我需要被簽名"}

response = requests.get(url, params=data, verify=False)
print(response.text)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM