我正在尝试使用来自我的网络服务器上的一个子域的不同webhook为(官方)Kik Chatbots运行多个NodeJs服务器。
但是,我无法做到这一点。对于一个机器人,它工作得很好。这是我对一个正在运行的NodeJs服务器的设置:
让我们假设所有的webhook都位于https://bots.mydomain.com
app.js:
'use strict';
let util = require('util');
let http = require('http');
let request = require('request');
let Bot = require('@kikinteractive/kik');
let bot = new Bot({
username: "foo",
apiKey: "bar",
baseUrl: "https://bots.mydomain.com"
});
bot.updateBotConfiguration();
// ... code ...
let server = http.createServer(bot.incoming()).listen(process.env.PORT || 8080);
所以这个Nodejs服务器基本上是在端口8080
上侦听。因此,我的网站https://bots.mydomain.com
的nginx配置如下所示:
server {
root /var/www/bots.mydomain.com/public_html;
index index.php index.html index.htm;
server_name bots.mydomain.com;
location / { proxy_pass http://localhost:8080/; } # Port 8080
}
到目前为止一切顺利。这很好用!但是问题:
如果我尝试运行多个NodeJs服务器,通过在public_html
文件夹中创建目录,让我们说/bot1
和/bot2
并调整我的nginx配置:
server {
root /var/www/bots.mydomain.com/public_html;
index index.php index.html index.htm;
server_name bots.mydomain.com;
location /bot1 { proxy_pass http://localhost:8080/; } # Port 8080
location /bot2 { proxy_pass http://localhost:8090/; } # Port 8090
}
并最终将第二台服务器设置为侦听端口8090
而不是8080
,当然还要将基本网址设置为https://bots.mydomain.com/bot1
或https://bots.mydomain.com/bot2
,这样就不再适用了。我的意思是webhooks不会将任何数据传递给NodeJs服务器。然而,它们正在运行!我知道这是因为如果我在机器人离线时导航到(例如)https://bots.mydomain.com
,我显然会收到错误502 Bad Gateway
但是如果机器人在线< / strong>我得到超时(这意味着服务器确实在监听)。
我是否遗漏了某些内容,或者Nginx是否不允许多个webhook或proxy_passes用于目录?
解决方法是为每个机器人创建一个子域,这可以工作(我尝试过)。但我想为机器人使用子目录而不是子域。
编辑:
我注意到一个奇怪的行为:如果我为/
喜欢:location / { proxy_pass http://localhost:8080; }
到端口8080并将bot1脚本中的baseurl设置为bots.mydomain.com/bot1
,Bot-1可以正常工作。
但我显然仍然无法让其他机器人工作,因为我正在使用根(/)。
这是否意味着Kik-API的收听方式存在问题?
编辑2 :
我现在检查了Nginx日志,看起来Kik Wrapper试图侦听一个不存在的目录。我做了以下操作:在端口8080
上启动机器人&amp;消息吧。这是日志输出:
2017/04/13 09:07:05 [error] 15614#15614: *1 open() "/var/www/bots.mydomain.com/public_html/incoming" failed (2: No such file or directory), client: 107.XXX.XXX.XXX, server: bots.mydomain.com, request: "POST /incoming HTTP/1.1", host: "bots.mydomain.com"
2017/04/13 09:07:13 [error] 15614#15614: *1 open() "/var/www/bots.mydomain.com/public_html/incoming" failed (2: No such file or directory), client: 107.XXX.XXX.XXX, server: bots.mydomain.com, request: "POST /incoming HTTP/1.1", host: "bots.mydomain.com"
但我仍然不知道如何解决这个问题。作为测试,我在incoming
中创建了目录public_html
。这在日志中返回以下内容:
2017/04/13 09:32:41 [error] 15614#15614: *10 directory index of "/var/www/bots.mydomain.com/public_html/incoming/" is forbidden, client: 107.XXX.XXX.XXX, server: bots.mydomain.com, request: "GET /incoming/ HTTP/1.1", host: "bots.mydomain.com"
有没有人知道如何修复它?
答案 0 :(得分:1)
我认为你的问题在于proxy_pass
中的尾部斜杠,它会在传递给上游时删除/bot1
和/bot2
前缀(仅用/
替换),因此,nodejs代码中的每个bot
都有一个不匹配的baseUrl
设置(正如您提到的那样,您确实更改了这些设置以匹配外部网址)。
-location /bot1 { proxy_pass http://localhost:8080/; } # Port 8080
-location /bot2 { proxy_pass http://localhost:8090/; } # Port 8090
+location /bot1 { proxy_pass http://localhost:8080; } # Port 8080
+location /bot2 { proxy_pass http://localhost:8090; } # Port 8090
答案 1 :(得分:0)
它可能不会因为您的目标服务器获得包含/bot1
和/bot2
前缀的路径而无法预期。
也许试试:
location /bot1 {
rewrite ^/bot1/(.*)$ /$1 break;
proxy_pass http://localhost:8080/;
}
location /bot2 {
rewrite ^/bot2/(.*)$ /$1 break;
proxy_pass http://localhost:8090/;
}
答案 2 :(得分:0)
万一有人遇到这个问题:
这是 Kik 的 API design 不可能的。
当你用
初始化你的机器人时let bot = new Bot({
username: "foo",
apiKey: "bar",
baseUrl: "https://bots.mydomain.com"
});
这个 baseUrl
本质上是一个 webhook,不能重复使用。它必须有点独特。
一种可能的解决方法是直接在 base-url 中指定端口。