1. Using the Test Server Provided by Us Directly
For convenience, we will open an HTTP website, access the console, and inject the following code.
- Please note that if you are using an HTTPS site, change
ws
towss
and configure the relevant certificate.
function SekiroClient(e){if(this.wsURL=e,this.handlers={},this.socket={},!e)throw new Error("wsURL can not be empty!!");this.webSocketFactory=this.resolveWebSocketFactory(),this.connect()}SekiroClient.prototype.resolveWebSocketFactory=function(){if("object"==typeof window){var e=window.WebSocket?window.WebSocket:window.MozWebSocket;return function(o){function t(o){this.mSocket=new e(o)}return t.prototype.close=function(){this.mSocket.close()},t.prototype.onmessage=function(e){this.mSocket.onmessage=e},t.prototype.onopen=function(e){this.mSocket.onopen=e},t.prototype.onclose=function(e){this.mSocket.onclose=e},t.prototype.send=function(e){this.mSocket.send(e)},new t(o)}}if("object"==typeof weex)try{console.log("test webSocket for weex");var o=weex.requireModule("webSocket");return console.log("find webSocket for weex:"+o),function(e){try{o.close()}catch(e){}return o.WebSocket(e,""),o}}catch(e){console.log(e)}if("object"==typeof WebSocket)return function(o){return new e(o)};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 e=this;try{this.socket=this.webSocketFactory(this.wsURL)}catch(o){return console.log("sekiro: create connection failed,reconnect after 2s:"+o),void setTimeout(function(){e.connect()},2e3)}this.socket.onmessage(function(o){e.handleSekiroRequest(o.data)}),this.socket.onopen(function(e){console.log("sekiro: open a sekiro client connection")}),this.socket.onclose(function(o){console.log("sekiro: disconnected ,reconnection after 2s"),setTimeout(function(){e.connect()},2e3)})},SekiroClient.prototype.handleSekiroRequest=function(e){console.log("receive sekiro request: "+e);var o=JSON.parse(e),t=o.__sekiro_seq__;if(o.action){var n=o.action;if(this.handlers[n]){var s=this.handlers[n],i=this;try{s(o,function(e){try{i.sendSuccess(t,e)}catch(e){i.sendFailed(t,"e:"+e)}},function(e){i.sendFailed(t,e)})}catch(e){console.log("error: "+e),i.sendFailed(t,":"+e)}}else this.sendFailed(t,"no action handler: "+n+" defined")}else this.sendFailed(t,"need request param {action}")},SekiroClient.prototype.sendSuccess=function(e,o){var t;if("string"==typeof o)try{t=JSON.parse(o)}catch(e){(t={}).data=o}else"object"==typeof o?t=o:(t={}).data=o;(Array.isArray(t)||"string"==typeof t)&&(t={data:t,code:0}),t.code?t.code=0:(t.status,t.status=0),t.__sekiro_seq__=e;var n=JSON.stringify(t);console.log("response :"+n),this.socket.send(n)},SekiroClient.prototype.sendFailed=function(e,o){"string"!=typeof o&&(o=JSON.stringify(o));var t={};t.message=o,t.status=-1,t.__sekiro_seq__=e;var n=JSON.stringify(t);console.log("sekiro: response :"+n),this.socket.send(n)},SekiroClient.prototype.registerAction=function(e,o){if("string"!=typeof e)throw new Error("an action must be string");if("function"!=typeof o)throw new Error("a handler must be function");return console.log("sekiro: register action: "+e),this.handlers[e]=o,this};
var client = new SekiroClient("ws://sekiro.iinti.cn:5612/business/register?group=test_web&clientId=" + Math.random());
client.registerAction("testAction", function (request, resolve, reject) {
resolve("ok");
});y
Successfully Established WebSocket Connection as Shown in the Image
Next, access the jsPRC link in the browser:
http://sekiro.iinti.cn/business/invoke?group=test_web&action=testAction¶m=testparm
You can see that the returned data corresponds to the injected code resolve("ok")
. In other words, you can replace it with something else in the injected code.
2. Self-Deployment
1. Server Installation
Sekiro supports three installation methods:
- Installation from Docker
- Using Docker Compose
- Manual local installation
For specific details, refer to the official documentation: Sekiro Server Installation
This article primarily focuses on the first method. The benefit of this approach is its convenience and speed, although it does have some limitations. Here’s an excerpt from the official documentation:
The one-click installation method using Docker does not require environment configuration. It only requires your Linux server to have a Docker environment to start up with a single click.
Its downside is slightly lower stability, as follows:
- Sekiro has two processes: a MySQL database and a Java service. In normal practice, the best practice is for a Docker image to only be associated with a specific process. Otherwise, if the process crashes, the Docker container cannot perceive it.
- It cannot achieve distributed scaling. Because it starts in an all-in-one manner, the database is hidden inside the Docker container, making it impossible to deploy multiple nodes and share the database among them.
Of course, in reality, I believe that a single server itself is already sufficient to support high concurrency pressure. I think a single Docker node is also sufficient for normal use.
- Step 1: Install Docker
yum install -y docker
- Step 2: Download the image
docker pull registry.cn-beijing.aliyuncs.com/iinti/common:sekiro3-allInOne-latest;
- Step 3: Start the Sekiro server
docker run -d -p 5612:5612 -v ~/sekiro-mysql-data:/var/lib/mysql --name sekiro-all-in-one registry.cn-beijing.aliyuncs.com/iinti/common:sekiro3-allInOne-latest
At this point, the server in the Docker container has started and is running on port 5612.
You can open the management interface in a browser at http://serverip:5612
for verification, for example: http://127.0.0.1:5612
You should be able to enter the management system successfully.
2. Some Interface Operations
- Account Registration: You can register an account on the interface from the previous step. The first registered account will become the administrator.
- Obtain your token: In the user information main interface, you can see your account’s token.
- Create Groups: In the group list, you can create groups.
3. Browser Injection
For convenience, we will open an HTTP website, access the console, and inject the following code.
function SekiroClient(e){if(this.wsURL=e,this.handlers={},this.socket={},!e)throw new Error("wsURL can not be empty!!");this.webSocketFactory=this.resolveWebSocketFactory(),this.connect()}SekiroClient.prototype.resolveWebSocketFactory=function(){if("object"==typeof window){var e=window.WebSocket?window.WebSocket:window.MozWebSocket;return function(o){function t(o){this.mSocket=new e(o)}return t.prototype.close=function(){this.mSocket.close()},t.prototype.onmessage=function(e){this.mSocket.onmessage=e},t.prototype.onopen=function(e){this.mSocket.onopen=e},t.prototype.onclose=function(e){this.mSocket.onclose=e},t.prototype.send=function(e){this.mSocket.send(e)},new t(o)}}if("object"==typeof weex)try{console.log("test webSocket for weex");var o=weex.requireModule("webSocket");return console.log("find webSocket for weex:"+o),function(e){try{o.close()}catch(e){}return o.WebSocket(e,""),o}}catch(e){console.log(e)}if("object"==typeof WebSocket)return function(o){return new e(o)};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 e=this;try{this.socket=this.webSocketFactory(this.wsURL)}catch(o){return console.log("sekiro: create connection failed,reconnect after 2s:"+o),void setTimeout(function(){e.connect()},2e3)}this.socket.onmessage(function(o){e.handleSekiroRequest(o.data)}),this.socket.onopen(function(e){console.log("sekiro: open a sekiro client connection")}),this.socket.onclose(function(o){console.log("sekiro: disconnected ,reconnection after 2s"),setTimeout(function(){e.connect()},2e3)})},SekiroClient.prototype.handleSekiroRequest=function(e){console.log("receive sekiro request: "+e);var o=JSON.parse(e),t=o.__sekiro_seq__;if(o.action){var n=o.action;if(this.handlers[n]){var s=this.handlers[n],i=this;try{s(o,function(e){try{i.sendSuccess(t,e)}catch(e){i.sendFailed(t,"e:"+e)}},function(e){i.sendFailed(t,e)})}catch(e){console.log("error: "+e),i.sendFailed(t,":"+e)}}else this.sendFailed(t,"no action handler: "+n+" defined")}else this.sendFailed(t,"need request param {action}")},SekiroClient.prototype.sendSuccess=function(e,o){var t;if("string"==typeof o)try{t=JSON.parse(o)}catch(e){(t={}).data=o}else"object"==typeof o?t=o:(t={}).data=o;(Array.isArray(t)||"string"==typeof t)&&(t={data:t,code:0}),t.code?t.code=0:(t.status,t.status=0),t.__sekiro_seq__=e;var n=JSON.stringify(t);console.log("response :"+n),this.socket.send(n)},SekiroClient.prototype.sendFailed=function(e,o){"string"!=typeof o&&(o=JSON.stringify(o));var t={};t.message=o,t.status=-1,t.__sekiro_seq__=e;var n=JSON.stringify(t);console.log("sekiro: response :"+n),this.socket.send(n)},SekiroClient.prototype.registerAction=function(e,o){if("string"!=typeof e)throw new Error("an action must be string");if("function"!=typeof o)throw new Error("a handler must be function");return console.log("sekiro: register action: "+e),this.handlers[e]=o,this};
var client = new SekiroClient("ws://127.0.0.1:5612/business/register?group=xxxx&clientId=" + Math.random());
client.registerAction("testAction", function (request, resolve, reject) {
resolve("ok");
});
In the above code, replace group=xxxx
with the group name you created in the second step.
Then, access the following URL in your browser: http://localhost:5612/business/invoke?group=sekiro_test&action=testAction&sekiro_token=xxxxx
In the code above, replace group=xxxx
and sekiro_token=xxxxx
with your own group name and token.
You can see that the returned data corresponds to the injected code resolve("ok")
. In other words, you can also replace it with something else in the injected code.