serverHandler.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. const net = require('net');
  2. const uuid = require('uuid');
  3. const http = require('http');
  4. let serverConfig = require('./server.json');
  5. /** 不能删,注册了全局方法 */
  6. const common = require('../utils/common');
  7. const lengthFieldDecoder = require('../lengthField/lengthFieldDecoder');
  8. const lengthFieldEncoder = require('../lengthField/lengthFieldEncoder');
  9. class serverHandler{
  10. constructor(configJson) {
  11. if(configJson){
  12. serverConfig = configJson;
  13. }else{
  14. }
  15. }
  16. start(){
  17. /** 客户端与服务器链接的MAP */
  18. let clientConnectSocketMap = new Map();
  19. let clientConnectTcpMap = new Map();
  20. let clientConnectSubdomainMap = new Map();
  21. /** 客户端注册的TCP穿透MAP */
  22. let clientTcpSocketMap = new Map();
  23. /** 客户端注册的TCP服务的Socket与服务之间的关系MAP */
  24. let clientTcpServerSocketMap = new Map();
  25. /** 客户端注册的子域名穿透MAP */
  26. let clientSubdomainConfigMap = new Map();
  27. /** http服务存储的map键值对 */
  28. let httpServerMap = new Map();
  29. let lengthFieldEncoderIns = new lengthFieldEncoder(4,100*1024*1024);
  30. // 创建TCP服务器
  31. const server = net.createServer((socket) => {
  32. // 保存客户端的连接
  33. let clientConnectChannelId = uuid.v1();
  34. clientConnectSocketMap.set(clientConnectChannelId,socket);
  35. let lengthFieldDecoderIns = new lengthFieldDecoder(4,100*1024*1024,function (completeData) {
  36. let receiveData = JSON.parse(completeData.toString());
  37. // 如果type:0 代表心跳
  38. if(receiveData.type === 0){
  39. let sendData = {
  40. type: 0,
  41. }
  42. socket.write(lengthFieldEncoderIns.encode(Buffer.from(JSON.stringify(sendData),"utf-8")));
  43. }else if(receiveData.type === 1){
  44. // 如果type:1 则表示客户端注册请求
  45. if(receiveData.token !== serverConfig.token){
  46. console.error("注册客户端token错误!");
  47. socket.end();
  48. return;
  49. }
  50. console.log(new Date().format("yyyy-MM-dd hh:mm:ss") + " 新客户端连接 clientConnectChannelId="+clientConnectChannelId)
  51. receiveData.data.forEach((register,index,arr) => {
  52. // 发送消息给客户端注册的状态
  53. let sendData = {
  54. type: 2,
  55. data:[
  56. ]
  57. }
  58. if(register.type === "tcp"){
  59. const clientTcpServer = net.createServer((clientTcpSocket) => {
  60. let clientTcpChannelId = uuid.v1();
  61. // 发送连接事件消息--有些tcp会让服务端先发消息,所以创建连接就通知是必要的
  62. let sendData = {
  63. channelId: clientTcpChannelId,
  64. type: 3,
  65. connect: true,
  66. data:{
  67. type: "tcp",
  68. localIp: register.localIp,
  69. localPort: register.localPort,
  70. trueData: Buffer.from([])
  71. }
  72. }
  73. socket.write(lengthFieldEncoderIns.encode(Buffer.from(JSON.stringify(sendData),"utf-8")));
  74. // 监听客户端的数据
  75. clientTcpSocket.on('data', (data) => {
  76. let sendData = {
  77. channelId: clientTcpChannelId,
  78. type: 3,
  79. data:{
  80. type: "tcp",
  81. localIp: register.localIp,
  82. localPort: register.localPort,
  83. trueData: data
  84. }
  85. }
  86. socket.write(lengthFieldEncoderIns.encode(Buffer.from(JSON.stringify(sendData),"utf-8")));
  87. });
  88. // 监听客户端断开连接事件
  89. clientTcpSocket.on('end', (data) => {
  90. clientTcpSocketMap.delete(clientTcpChannelId);
  91. });
  92. clientTcpSocket.on('error', (error) => {
  93. clientTcpSocketMap.delete(clientTcpChannelId);
  94. });
  95. clientTcpSocketMap.set(clientTcpChannelId,clientTcpSocket);
  96. clientTcpServerSocketMap.set(clientTcpSocket,clientTcpServer);
  97. })
  98. // 启动服务
  99. clientTcpServer.listen(register.port, () => {
  100. clientConnectTcpMap.set(clientTcpServer,clientConnectChannelId);
  101. sendData.data.push({msg:"tcp port:" + register.port + " success"});
  102. socket.write(lengthFieldEncoderIns.encode(Buffer.from(JSON.stringify(sendData),"utf-8")));
  103. });
  104. clientTcpServer.on("error",function (error) {
  105. console.error("客户端通道失败",error);
  106. sendData.data.push({msg:"tcp port:" + register.port + " fail"});
  107. socket.write(lengthFieldEncoderIns.encode(Buffer.from(JSON.stringify(sendData),"utf-8")))
  108. })
  109. }else if(register.type === "http"){
  110. if(null == clientConnectSubdomainMap.get(register.subdomain)){
  111. clientConnectSubdomainMap.set(register.subdomain,clientConnectChannelId);
  112. clientSubdomainConfigMap.set(register.subdomain,register);
  113. sendData.data.push({msg:"http subdomain:" + register.subdomain + " success"});
  114. }else{
  115. sendData.data.push({msg:"http subdomain:" + register.subdomain + " fail"});
  116. }
  117. socket.write(lengthFieldEncoderIns.encode(Buffer.from(JSON.stringify(sendData),"utf-8")))
  118. }
  119. })
  120. }else if(receiveData.type === 4){
  121. if(receiveData.data.type === "tcp"){
  122. let cacheClientTcp = clientTcpSocketMap.get(receiveData.channelId);
  123. if(null != cacheClientTcp){
  124. cacheClientTcp.write(Buffer.from(receiveData.data.trueData));
  125. }
  126. }else if(receiveData.data.type === "http"){
  127. let httpServer = httpServerMap.get(receiveData.channelId);
  128. if(null != httpServer){
  129. httpServer.res.writeHead(receiveData.data.statusCode, receiveData.data.headers);
  130. httpServer.res.end(Buffer.from(receiveData.data.body));
  131. // 由于HTTP请求是单次请求,请求发送结束后就可以删除该绑定通道
  132. httpServerMap.delete(receiveData.channelId);
  133. }
  134. }
  135. }else if(receiveData.type === 5){
  136. // 接收到客户端发来的失败状态消息
  137. if(receiveData.data.type === "tcp"){
  138. let cacheClientTcp = clientTcpSocketMap.get(receiveData.channelId);
  139. if(null != cacheClientTcp){
  140. cacheClientTcp.end();
  141. }
  142. }else if(receiveData.data.type === "http"){
  143. let httpServer = httpServerMap.get(receiveData.channelId);
  144. if(null != httpServer){
  145. httpServer.res.writeHead(500);
  146. httpServer.res.end(Buffer.from(JSON.stringify(receiveData.data.body)));
  147. // 由于HTTP请求是单次请求,请求发送结束后就可以删除该绑定通道
  148. httpServerMap.delete(receiveData.channelId);
  149. }
  150. }
  151. }
  152. });
  153. // 监听客户端的数据
  154. socket.on('data', (data) => {
  155. try{
  156. lengthFieldDecoderIns.read(data);
  157. }catch (error) {
  158. console.error("通道数据异常",error);
  159. }
  160. });
  161. // 监听客户端断开连接事件
  162. socket.on('end', (data) => {
  163. console.log('客户端断开连接')
  164. });
  165. // 监听客户端断开连接事件
  166. socket.on('error', (error) => {
  167. console.log(new Date().format("yyyy-MM-dd hh:mm:ss") + ' 客户端异常关闭 clientConnectChannelId='+clientConnectChannelId,error);
  168. socket.end();
  169. // 删除客户端与服务端的连接
  170. clientConnectSocketMap.delete(clientConnectChannelId);
  171. // 删除客户端注册的TCP穿透连接
  172. clientConnectTcpMap.forEach((v,k,map)=>{
  173. if(v === clientConnectChannelId){
  174. clientTcpServerSocketMap.forEach((vc,kc,map) => {
  175. if(vc === k){
  176. kc.end();
  177. clientTcpServerSocketMap.delete(kc);
  178. }
  179. })
  180. k.close();
  181. clientConnectTcpMap.delete(k);
  182. }
  183. });
  184. // 删除客户端注册的HTTP穿透连接
  185. clientConnectSubdomainMap.forEach((v,k,map)=>{
  186. if(v === clientConnectChannelId){
  187. // 删除HTTP穿透配置
  188. clientSubdomainConfigMap.delete(k);
  189. clientConnectSubdomainMap.delete(k);
  190. }
  191. })
  192. });
  193. });
  194. // 启动服务
  195. server.listen(serverConfig.bindPort, () => {
  196. console.log(new Date().format("yyyy-MM-dd hh:mm:ss") + ' 服务创建成功 tcp port:'+serverConfig.bindPort)
  197. });
  198. server.on("error", function (error) {
  199. console.error("服务启动失败",error)
  200. })
  201. http.createServer(function (req, res) {
  202. let channelId = uuid.v1();
  203. httpServerMap.set(channelId,{req:req,res:res});
  204. // 定义了一个post变量,用于暂存请求体的信息
  205. let post = [];
  206. // 通过req的data事件监听函数,每当接受到请求体的数据,就累加到post变量中
  207. //当有数据请求时触发
  208. req.on('data', function(data){
  209. if(post.length === 0){
  210. post = data;
  211. }else{
  212. post = Buffer.concat([post,data]);
  213. }
  214. });
  215. req.on('end', function(){
  216. try{
  217. let subdomain = req.headers.host.substring(0,req.headers.host.indexOf(serverConfig.subdomainHost) - 1);
  218. let clientConnectChannelId = clientConnectSubdomainMap.get(subdomain);
  219. let clientSubdomainConfig = clientSubdomainConfigMap.get(subdomain);
  220. if(null == clientConnectChannelId || null == clientConnectSocketMap.get(clientConnectChannelId)){
  221. res.writeHead(404);
  222. res.end(Buffer.from("cros not find "+req.headers.host+" config!","utf-8"));
  223. httpServerMap.delete(channelId);
  224. return;
  225. }
  226. let cacheClientConnect = clientConnectSocketMap.get(clientConnectChannelId);
  227. let transData = {
  228. type: "http",
  229. localIp: clientSubdomainConfig.localIp,
  230. localPort: clientSubdomainConfig.localPort,
  231. headers: req.headers,
  232. url: req.url,
  233. method: req.method,
  234. postData: [...post]
  235. }
  236. let initData = {
  237. channelId: channelId,
  238. type: 3,
  239. data: transData
  240. }
  241. cacheClientConnect.write(lengthFieldEncoderIns.encode(Buffer.from(JSON.stringify(initData),"utf-8")));
  242. }catch (error) {
  243. console.log("http数据异常",error);
  244. }
  245. });
  246. }).listen(serverConfig.bindHttpPort);
  247. console.log(new Date().format("yyyy-MM-dd hh:mm:ss") + ' Server running at http://127.0.0.1:'+serverConfig.bindHttpPort+'/');
  248. }
  249. }
  250. module.exports = serverHandler;