02月07, 2021

node.js 调用 v2ray API 添加用户

简介

SSR 服务用了好久了,自己造了不少轮子了。现在看到 v2ray 发展还是不错的,打算接入自己的服务。 花了一点儿时间研究明白了里面的这些配置文件。 思考如何单端口多用户,并且实时更新。下面来简单讲解一下node.js 调用 v2ray API 添加用户的流程。

首先讲一下坑点,Golang 一点儿不会,看着代码比较头疼,对 gRPC 不是很熟悉,花了时间来研究,接入代码的时候坑也是很多,网上基本没有靠谱的例子,有goLang 的例子很快就跑通了,但是不是很符合我的要求,于是乎花点儿时间研究一下如何使用 js 来调用 v2ray grpc api。

踩坑合集

1. proto 文件

网上大多的教程是从 proto 文件开始的,直接说重点,proto文件有两种使用模式

  1. 动态编译,使用 grpc/proto-loader 这个库(v2ray 这边不好用,至少我没有搞定)
  2. 静态编译,用 https://www.npmjs.com/package/grpc-tools 这个库
  3. 坑 ,看了这个例子之后 https://www.tuicool.com/articles/mqArUbI 让自己迷茫了一下,这么多库 既然这个有样子就照着葫芦画瓢,浪费了很多时间,最后放弃 https://github.com/protobufjs/protobuf.js 这个库编译完了之后没有 grpc 这样的文件,grpc 那边的逻辑还要自己弄 。避免避免

推荐还是静态编译,这样一次编译终身使用,不用每次都编译,这样效率比较高

2. 编译 proto 文件

编译的时候 很头疼,官方给出的例子非常少!!! 而且藏得比较深。 https://github.com/grpc/grpc/tree/master/examples/node/static_codegen 地址贴来了。 这样只能跑通官方的例子,然鹅对待 v2ray 的还是不行,因为里面有了 import 并且需要别的库预先编译,比如 serial 里面的还有 protocol 里面的一些文件。 这样的方法不行的!!! 要从命令参数下功夫,最终会生成 *_grpc_pb.js 还有 *_pb.js 文件。 第一个可以认为是 service 第二个则是信封(参照 java)。

下面给出正确的指令,新建一个文件夹,里面按照 v2ray 里面的 proto 的 结构复制一下。

然后进入这个目录,执行命令, 这样的命令会把所有的 proto 都编译了,这样就没有了依赖的问题!!! 记得自己建一个 src 目录 在上级目录。 这个命令研究了好久,里面提示不够准确啥的。

grpc_tools_node_protoc --proto_path=./ --js_out=import_style=commonjs,binary:../src  --grpc_out=../src --plugin=protoc-gen-grpc=`which grpc_tools_node_protoc_plugin` $(find . -type f -name "*.proto")

3. 另一种方法 不推荐

此方法会生成一个文件,最后没有 grpc 的命令,要自己来处理, 这里是 1.3 里面提到的那个库,劝退!

pbjs -t static-module -w commonjs  xxx.proto

这样只能编译一个,所以也需要处理命令 把所有的库都弄一下。

4. 开始代码

头部主要引入文件

const grpc = require('grpc');
const message = require('./src/app/proxyman/command/command_pb');
const service = require('./src/app/proxyman/command/command_grpc_pb');
const protocol = require('./src/common/protocol/user_pb');
const serial = require('./src/common/serial/typed_message_pb');
const vmess = require('./src/proxy/vmess/account_pb');
const {v4: uuidv4} = require('uuid');

const handlerServiceClient = new service.HandlerServiceClient('localhost:8080', grpc.credentials.createInsecure());

新坑开始,看到了 https://github.com/v2ray/v2ray-core/issues/1856 虽然作者轻描淡写了一下,但是确实是个问题。 类名没有办法拿到,这里参照了 Python 的 api 也参考了 golang 的 api,里面的那个方法都能拿到对应的类名,而 js 里面没有!!! 这个方法也要自己写一下, 最后的 效果 打印出请求应该是这样的

  messageId_: undefined,
  arrayIndexOffset_: -1,
  array: [
    'proxy',
    [
      'v2ray.core.app.proxyman.command.RemoveUserOperation',
      [Uint8Array]
    ]
  ],
  pivot_: 1.7976931348623157e+308,
  convertedPrimitiveFields_: {}
}

踩坑 1 天,好了 就先写到这里。 有需要的打赏呗 :)

https://pay.qfdk.me/

本文链接:https://blog.qfdk.me/post/node.js gRPC diao-yong- v2ray API.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。