Skip to content

Commit

Permalink
Merge branch 'release/v1.0.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
zhihuihu committed Dec 29, 2020
2 parents c78a1d8 + 0d76016 commit 2901b3e
Show file tree
Hide file tree
Showing 8 changed files with 905 additions and 416 deletions.
39 changes: 34 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,43 @@
* ### http内网穿透
* ### 其他功能暂时不想开发

### server.config配置
```
* 项目clone下来
### 项目说明
* 项目分为服务端和客户端
* 服务端 为部署在公网服务器的一端接收整个请求
* 客户端 为部署在用户内网中,转发公网过来的请求,路由到指定服务
* 项目可以采用如下两种方式部署
* 一、采用脚手架部署客户端和服务端
* npm install cros -g
* 运行服务端 cros server serverConfig.json
* serverConfig.json 是服务端的配置文件路径,具体配置在下面
* 运行客户端 cros client clientConfig.json
* clientConfig.json 是服务端的配置文件路径,具体配置在下面
* 二、采用源码方式部署客户端和服务端
* 项目clone下来 git clone https://github.com/zhihuihu/cros.git
* 执行 npm install
* 然后配置一下文件,分为服务端和客户端

### 服务端nginx配置(如果需要域名穿透)
```shell script
# node内网穿透
server {
listen 80;
# 泛型域名
server_name *.crosn.aaa.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host:80;
proxy_set_header X-Nginx-Proxy true;
proxy_set_header Connection "";
# 服务端配置的http的端口
proxy_pass http://127.0.0.1:7101/;
}
}
```
### server.config配置
```
* 服务端启动 node ./server/server.js*
* 服务端启动 node ./server/server.js 或者脚手架启动 cros server serverConfig.json *
{
// 服务开启的tcp端口供服务端和客户端通信
"bindPort": 8080,
Expand All @@ -27,7 +56,7 @@
### client.json配置

```
* 客户端启动 node ./client/client.js *
* 客户端启动 node ./client/client.js 或者脚手架启动 cros client clientConfig.json *
{
// 服务端的IP地址
"serverIp": "127.0.0.1",
Expand Down
61 changes: 61 additions & 0 deletions bin/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env node
const commander = require('commander');
const inquirer = require('inquirer'); //命令行答询
const ora = require('ora'); //命令行中加载状态标识
const chalk = require('chalk'); //命令行输出字符颜色
const fs = require('fs');
const path = require("path");
const serverHandler = require('../server/serverHandler');
const clientHandler = require('../client/clientHandler');
const projectPackage = require('../package.json');

// 工具版本号
commander.version(projectPackage.version);

commander
.command('server <configPath>')
.description('start the cros server')
.action(function (configPath) {
let serverConfig;
if(path.isAbsolute(configPath)){
if(!fs.existsSync(configPath)){
console.log(chalk.red(`[cros] The configuration file does not exist`));
return 0;
}
serverConfig = JSON.parse(fs.readFileSync(configPath).toString());
}else{
let truePath = path.resolve('./', configPath);
if(!fs.existsSync(truePath)){
console.log(chalk.red(`[cros] The configuration file does not exist`));
return 0;
}
serverConfig = JSON.parse(fs.readFileSync(truePath).toString());
}
let serverHandlerIns = new serverHandler(serverConfig);
serverHandlerIns.start();
});

commander
.command('client <configPath>')
.description('start the cros client')
.action(function (configPath) {
let serverConfig;
if(path.isAbsolute(configPath)){
if(!fs.existsSync(configPath)){
console.log(chalk.red(`[cros] The configuration file does not exist`));
return 0;
}
serverConfig = JSON.parse(fs.readFileSync(configPath).toString());
}else{
let truePath = path.resolve('./', configPath);
if(!fs.existsSync(truePath)){
console.log(chalk.red(`[cros] The configuration file does not exist`));
return 0;
}
serverConfig = JSON.parse(fs.readFileSync(truePath).toString());
}
let clientHandlerIns = new clientHandler(serverConfig);
clientHandlerIns.start();
});

commander.parse(process.argv);
183 changes: 3 additions & 180 deletions client/client.js
Original file line number Diff line number Diff line change
@@ -1,183 +1,6 @@
const net = require('net');
const http = require('http');
const clientConfig = require('./client.json');
const lengthFieldDecoder = require('../lengthField/lengthFieldDecoder');
const lengthFieldEncoder = require('../lengthField/lengthFieldEncoder');
const common = require('../utils/common');

// 心跳助手
let idleStateHandler;
// 重连助手
let reconnectHandler;
// 连接状态
let connectFlag;
let tcpClientMap = new Map();
let lengthFieldEncoderIns = new lengthFieldEncoder(4,100*1024*1024);
let lengthFieldDecoderIns = new lengthFieldDecoder(4,100*1024*1024,function(completeData){
let receiveData = JSON.parse(completeData.toString());
// 如果是心跳回复消息则不处理
if(receiveData.type === 0){

}else if(receiveData.type === 2){
// 接收到注册结果消息
connectFlag = true;
clearInterval(reconnectHandler);
if(!idleStateHandler){
idleStateHandler = setInterval(function () {
let sendData = {
type: 0,
}
client.write(lengthFieldEncoderIns.encode(Buffer.from(JSON.stringify(sendData),"utf-8")));
},30000);
}
receiveData.data.forEach((result)=>{
console.log(new Date().format("yyyy-MM-dd hh:mm:ss") + " " + result.msg);
})
}else if(receiveData.type === 3){
// 接收到请求数据
if(receiveData.data.type === "tcp"){
let cacheTcpClient = tcpClientMap.get(receiveData.channelId);
if(null != cacheTcpClient){
cacheTcpClient.write(Buffer.from(receiveData.data.trueData))
}else{
// 连接服务器
const tcpClient = net.connect({host: receiveData.data.localIp,port: receiveData.data.localPort}, () => {
tcpClient.write(Buffer.from(receiveData.data.trueData))
tcpClientMap.set(receiveData.channelId,tcpClient);
})
// 接收服务端的数据
tcpClient.on('data', (data) => {
let sendData = {
type: 4,
channelId: receiveData.channelId,
data: {
type: "tcp",
trueData: data
}
}
client.write(lengthFieldEncoderIns.encode(Buffer.from(JSON.stringify(sendData),"utf-8")));
})
// 断开连接
tcpClient.on('end', () => {
tcpClientMap.forEach((v,k)=>{
if(v == tcpClient){
// 删除连接
tcpClientMap.delete(k);
}
})
})
tcpClient.on("error",(error)=>{
let responseData = {
type: "tcp",
code: "error",
body: error
}
// 数据接收完成
let sendData = {
channelId: receiveData.channelId,
type: 5,
data: responseData
}
client.write(lengthFieldEncoderIns.encode(Buffer.from(JSON.stringify(sendData),"utf-8")));
})
}
}else if(receiveData.data.type === "http"){
let options = {
host: receiveData.data.localIp,
port: receiveData.data.localPort,
method: receiveData.data.method,
path: receiveData.data.url,
headers: receiveData.data.headers
};
let callback = function(response){
let body = [];
response.on('data', function(data) {
if(body.length === 0){
body = data;
}else{
body = Buffer.concat([body,data]);
}
});
response.on('end', function() {
let responseData = {
type: "http",
statusCode: response.statusCode,
headers: response.headers,
body: [...body]
}
// 数据接收完成
let sendData = {
channelId: receiveData.channelId,
type: 4,
data: responseData
}
client.write(lengthFieldEncoderIns.encode(Buffer.from(JSON.stringify(sendData),"utf-8")));
});
}
// 向服务端发送请求
let req = http.request(options, callback);
req.on("error", (error)=>{
let responseData = {
type: "http",
code: "error",
body: error
}
// 数据接收完成
let sendData = {
channelId: receiveData.channelId,
type: 5,
data: responseData
}
client.write(lengthFieldEncoderIns.encode(Buffer.from(JSON.stringify(sendData),"utf-8")));
})
if(receiveData.data.postData && receiveData.data.postData.length > 0){
req.write(Buffer.from(receiveData.data.postData))
}
req.end();
}
}
})
// 连接服务器
let client = connect();

/**
* 连接服务器
* @returns {Socket}
*/
function connect(){
let connectClient = net.connect({host: clientConfig.serverIp,port: clientConfig.serverPort}, () => {
let sendData = {
type: 1,
token: clientConfig.token,
data: clientConfig.registers
}
connectClient.write(lengthFieldEncoderIns.encode(Buffer.from(JSON.stringify(sendData),"utf-8")));
});
// 接收服务端的数据
connectClient.on('data', (data) => {
try{
lengthFieldDecoderIns.read(data);
}catch (error) {
console.error("通道数据异常",error);
}
})
// 断开连接
connectClient.on('end', () => {

})
connectClient.on("error", (error)=>{
console.error(new Date().format("yyyy-MM-dd hh:mm:ss") + " 异常",error);
// 断线重连
connectClient.end();
clearInterval(reconnectHandler);
clearInterval(idleStateHandler);
idleStateHandler = null;
connectFlag = false;
reconnectHandler = setInterval(function () {
client = connect();
},10000);
})
return connectClient;
}
const clientHandler = require('./clientHandler');

let clientHandlerIns = new clientHandler(clientConfig);
clientHandlerIns.start();

Loading

0 comments on commit 2901b3e

Please sign in to comment.