мы пытаемся подключиться к узлу geth через WebSockets, чтобы иметь возможность подписаться на события контракта.Этот узел создается с помощью Docker, и этот докер использует nginx в качестве прокси.
Мы можем легко подключиться с помощью http (не WS rpc), но мы не можем подписаться на события контракта с помощью http.
Мыудалось установить соединение в локальном экземпляре этого образа докера с сервером веб-сокетов nodejs с тем же прокси-сервером nginx.Но мы не можем соединиться с web3 v1.0.0-beta55.
Мы получаем две разные ошибки: 403 (Запрещено) с этой конфигурацией nginx (которая работает с веб-сокетами не web3):
location /rpcws {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://localhost:22001;
}
или ошибка 400 (неверный запрос) с этой другой конфигурацией:
location /rpcws {
proxy_pass http://localhost:22001;
}
На стороне клиента мы получаем
Error during WebSocket handshake: Unexpected response code: 400||403
или
connection not open on send()
Прямо сейчас мы отслеживаем возможные проблемы с портом в локальном экземпляре этого образа докера, но мы несколько раз настраивали узел для получения этого ws-соединения через уже работающий порт http rpc (очевидно, меняя все настройки geth и nginx наполучить wsrpc, а не http rpc), и мы получим те же коды ошибок.
Наше основное предположение состоит в том, что nginx неправильно выполняет proxy_passing запроса WebSocket.Мы обратились к технической команде сети кворума, и они никогда не пытались установить соединение с WebSocket, и они не знают, как нам помочь в дальнейшем.Любое предположение хорошо принято.
Спасибо!
Весь код указан ниже.
Интеллектуальный контракт на надежность:
pragma solidity 0.4.18;
contract EventTest {
string fName;
uint age;
event doSetInstructor();
event instructorSetted(string name, uint age);
function askForSetInstructor() public {
doSetInstructor();
}
function setInstructor(string _fName, uint _age) public {
fName = _fName;
age = _age;
instructorSetted(fName, age);
}
function getInstructor() public constant returns (string, uint) {
return (fName, age);
}
}
Соединение Web3:
var Web3 = require('web3');
var TruffleContract = require('truffle-contract');
var eventTestABI = require('./abi/EventTest.json');
var io = require('socket.io-client');
var web3 = new Web3(new Web3.providers.WebsocketProvider('ws://9.43.80.817/rpcws'));
var contractAddress;
web3.eth.defaultAccount = '0x41E4e56603bF37a03Bb5Asa635787b3068052b82';
let truffleContract = TruffleContract(eventTestABI);
contractAddress = '0x82ce1df01f2a8bcadfad485eaa785424123734f7';
let contract = new web3.eth.Contract(eventTestABI.abi, contractAddress, {
from: '0x41E4e56603bF37a03Bb5Asa635787b3068052b82',
gas: 20000000,
gasPrice: 0,
data: truffleContract.deployedBytecode
});
web3.eth.subscribe('logs', {
address: contract.options.address,
topics: [contract.events.doSetInstructor().signature]
}, (error, result) => {
if (!error) {
console.log("Event triggered");
const eventObj = web3.eth.abi.decodeLog(
eventJsonInterface.inputs,
result.data,
result.topics.slice(1)
)
console.log("New event!", eventObj)
console.log(eventObj);
}else{
console.log("Error watching event", error);
}
});
Настройка geth:
--networkid $NETID --identity $IDENTITY --permissioned --ws --wsaddr 0.0.0.0
--wsport 22001 --wsapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,
istanbul --wsorigins '*' --rpc --rpcaddr $RPCADDR --rpcapi admin,db,eth,debug,miner,
net,shh,txpool,personal,web3,quorum,istanbul --rpccorsdomain '*' --rpcport 22000
--port 21000 --istanbul.requesttimeout 10000 --ethstats $IDENTITY --verbosity 3 --vmdebug --emitcheckpoints --targetgaslimit 18446744073709551615 --syncmode full --gcmode $GCMODE --vmodule consensus/istanbul/core/core.go=5 --nodiscover
Файл конфигурации nginx:
limit_req_zone $binary_remote_addr zone=one:10m rate=999999999999999999r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;
client_body_buffer_size 128k;
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
root /var/www/html;
access_log /var/log/nginx/access_log combined;
error_log /var/log/nginx/error.log warn;
index index.html index.htm index.nginx-debian.html;
#ssl_certificate /etc/ssl/nginx/alastria-test.crt;
#ssl_certificate_key /etc/ssl/nginx/alastria-test.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
client_body_timeout 30s;
client_header_timeout 30s;
add_header 'Access-Control-Allow-Headers' 'Content-Type';
add_header 'Access-Control-Allow-Origin' "http://someurl.com";
location / {
# First attempt to serve request as file, then as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
location /rpcws {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://localhost:22001;
}
location /rpc {
# Request rate and number of connections limitation
limit_req zone=one burst=30 nodelay;
limit_conn addr 10;
# Whitelist/Blacklist
include ./conf.d/blacklist;
content_by_lua_block {
ngx.req.read_body()
local data = ngx.req.get_body_data()
if data then
if not (string.match(data,"eth_") or string.match(data,"net_") or string.match(data,"web3_") or string.match(data, "personal_")) then
ngx.exit(403)
else
ngx.exec("@rpc_proxy")
end
end
}
}
location @rpc_proxy {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_pass http://localhost:22000;
}
}