Error during web socket handshake; websocket connection failed, using autobahn.js - websocket

I am trying to create a websocket server using Ratchet, React and Autobahn. When trying to connect I get this error in console
autobahn.min.js:196 WebSocket connection to 'ws://localhost:8090/'
failed: Error during WebSocket handshake: Unexpected response code:
426
During some digging in Google I found out that Ratchet supports only WAMP1, but that information was 2014. Is this still relevant?
This is the JS
var connection = new autobahn.Connection({
transports: [{
type: 'websocket',
port: 8090,
host: 'localhost',
url: 'ws://localhost:8090'
}],
realm: 'realm1'
});
connection.open();
This is the WebsocketController class
<?php
namespace App\Http\Controllers;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Wamp\WampServerInterface;
class WebSocketController extends Controller implements WampServerInterface{
private $connections = [];
protected $subscribedTopics = array();
public function onSubscribe(ConnectionInterface $conn, $topic) {
$this->subscribedTopics[$topic->getId()] = $topic;
}
public function onUnSubscribe(ConnectionInterface $conn, $topic) {
}
public function onOpen(ConnectionInterface $conn) {
$this->connections->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
}
public function onClose(ConnectionInterface $conn) {
}
public function onCall(ConnectionInterface $conn, $id, $topic, array $params) {
// In this application if clients send data it's because the user hacked around in console
$conn->callError($id, $topic, 'You are not allowed to make calls')->close();
}
public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible) {
// In this application if clients send data it's because the user hacked around in console
$conn->close();
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "New error!".$e;
}
/**
* #param string JSON'ified string we'll receive from ZeroMQ
*/
public function onBlogEntry($entry) {
$entryData = json_decode($entry, true);
// If the lookup topic object isn't set there is no one to publish to
if (!array_key_exists($entryData['category'], $this->subscribedTopics)) {
return;
}
$topic = $this->subscribedTopics[$entryData['category']];
// re-send the data to all the clients subscribed to that category
$topic->broadcast($entryData);
}
}
This is the server:
$loop = Factory::create();
$pusher = new WebsocketController;
// Listen for the web server to make a ZeroMQ push after an ajax request
$context = new Context($loop);
$pull = $context->getSocket(\ZMQ::SOCKET_PULL);
$pull->bind('tcp://127.0.0.1:5555'); // Binding to 127.0.0.1 means the only client that can connect is itself
$pull->on('message', array($pusher, 'onBlogEntry'));
// Set up our WebSocket server for clients wanting real-time updates
$webSock = new \React\Socket\Server('0.0.0.0:8090', $loop); // Binding to 0.0.0.0 means remotes can connect
$webServer = new \Ratchet\Server\IoServer(
new \Ratchet\Http\HttpServer(
new \Ratchet\WebSocket\WsServer(
new \Ratchet\Wamp\WampServer(
$pusher
)
)
),
$webSock
);
$loop->run();
Headers
Request URL:ws://localhost:8090/
Request Method:GET
Status Code:426 No Sec-WebSocket-Protocols requested supported
Response Headers
view source
Connection:Upgrade
Sec-WebSocket-Protocol:0
Sec-WebSocket-Version:13
Transfer-Encoding:chunked
Upgrade:websocket
X-Powered-By:Ratchet/0.4
Request Headers
view source
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.9,et;q=0.8
Cache-Control:no-cache
Connection:Upgrade
Host:localhost:8090
Origin:http://ermp.ee:8000
Pragma:no-cache
Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits
Sec-WebSocket-Key:GbJ7qf3lzKDE2hmh3mxJpQ==
Sec-WebSocket-Protocol:wamp.2.json, wamp.2.msgpack
Sec-WebSocket-Version:13
Upgrade:websocket
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36
What am I doing wrong here?

I was making something similar to your program when I encountered with this problem. I realized that I was running localhost on the wrong port AND I had processes like Skype running in background on my desired selected port.
Local host runs on port 8000.
Change your code above to this and try as this worked for me in one of my projects
var connection = new autobahn.Connection({
transports: [{
type: 'websocket',
port: 8000,
host: 'localhost',
url: 'ws://localhost:8000'
}],
realm: 'realm1'
});
connection.open();
Also check on your computer if there is already an application running on port 8000, if it is end the program/process to solve the problem.
In Server:
$webSock = new \React\Socket\Server('0.0.0.0:8000', $loop); // Binding to 0.0.0.0 means remotes can connect
In Headers:
Host:localhost:8000
And you right ratchet does support only wamp1
Maybe you can switch ratchet to thruway which may solve problem

I switched from Ratchet to ThruwayPHP and it started working immediately if somebody else has the same issue.

Related

Pixel 2 API 29 httpClient not working correctly

I have finally released a nativescript app to the store. iOS is good, almost all versions of Android are good. However, someone downloaded onto a Pixel 2 with API 29 and told me they couldn't login. I downloaded an emulator and sure enough, the http request never goes through.
This is my login code in my service:
getLogin(args): RxObservable<Object> {
var params = this.buildQueryParams(args);
let headers = this.createRequestHeader();
return this.http.get(`${this.serverUrl}AuthenticateUser${params}`);
}
This is my login component using it:
login() {
this.isLoggingIn = true;
Object.assign(this.user, this.loginForm.value);
this.httpSub = this.httpget.getLogin(this.user)
.pipe(
map(res=>res),
catchError((err: string) => {
const errMsg = "There was a network error, please check your connection or try again later";
return of(errMsg)
})
)
.subscribe((result) => {
if(result['Status'] === "SUCCESS"){
this.onGetDataSuccess(result);
}
else if(typeof(result) === 'string'){
this.errorMessage = "There is a connection error.";
this.isLoggingIn = false;
}
else {
this.errorMessage = "user name or password incorrect";
this.isLoggingIn = false;
}
}, (error) => {
console.log("got an error");
this.errorMessage = "Verify your username and password. If you have an account, but are having trouble, call 1-866-706-8665.";
this.isLoggingIn = false;
});
I'm getting this on the Pixel:
There is a connection error.
In the debugger this is what I see in the Headers on the pixel:
Request URL: http://toolingu.com/ToolingU.WCF.TuAppService/ToolingU.WCF.TuAppService.svc/AuthenticateUser?username=<user>&password=<pw>
Referrer Policy: no-referrer-when-downgrade
Provisional headers are shown
Accept: application/json, text/plain, */*
username: <user>
password: <pw>
This is what I see on the emulators that are working correctly:
Request URL: http://toolingu.com/ToolingU.WCF.TuAppService/ToolingU.WCF.TuAppService.svc/AuthenticateUser?username=<user>&password=<pw>
Request Method: GET
Status Code: 200 OK
Referrer Policy: no-referrer-when-downgrade
Provisional headers are shown
Accept: application/json, text/plain, */*
username: <user>
password: <pw>
It appears the error happens instantly, as if it isn't waiting for a response to come back. Any ideas?
Http communications (clear text traffic) are blocked by default from Android Pie (API 29). You will have to enable it by explicitly by adding android:usesCleartextTraffic="true" on application tag of your AndroidManifest.xml

How to call a https POST method using gatewayscript in IBM Bluemix APIConnect

I am trying to call another API inside Bluemix or any other HTTPS post method using a gateway script inside IBM Bluemix (API Connect) using the code below:
var urlopen = require('urlopen');
var options = {
target: 'https://pokemons.mybluemix.net/api/pokemons/1',
method: 'POST',
headers: {},
contentType: 'application/json',
timeout: 60,
data: {"Message": "DataPower GatewayScript"}
};
urlopen.open(options, function(error, response) {
if (error) {
// an error occurred during the request sending or response header parsing
session.output.write("urlopen error: "+JSON.stringify(error));
} else {
// get the response status code
var responseStatusCode = response.statusCode;
var responseReasonPhrase = response.reasonPhrase;
console.log("Response status code: " + responseStatusCode);
console.log("Response reason phrase: " + responseReasonPhrase);
// reading response data
response.readAsBuffer(function(error, responseData){
if (error){
throw error ;
} else {
session.output.write(responseData) ;
apim.output('application/json');
}
});
}
});
But I am getting the following error:
{
"httpCode": "500",
"httpMessage": "Internal Server Error",
"moreInformation": "URL open: Cannot create connection to 'https://pokemons.mybluemix.net/api/pokemons/1', status code: 7"
}
Looks like there is some issue with the SSL Connections. If so, how can I get the SSL Details for the default Sandbox Catalog in IBM Bluemix API Connect? Or, how can I make the HTTPS POST calls to the above sample URL?
Since Version 5.0.6:
IBM API Connect 5.0.x
Forward SSLProxy (and Crypto) is replaced with SSLClient. These new profiles support ephemeral ciphers (DHE and ECDHE), perfect forward secrecy, and Server Name Indication (SNI) extension. Note that DHE ciphers in DataPower SSLServerProfile use 2048-bit DH parameters (as server) and accept 1024-bit DH parameters (as client).
In order for you specific example to work on API Connect using HTTPS you need to specify the sslClientProfile.
For example:
var urlopen = require('urlopen');
var options = {
target: 'https://pokemons.mybluemix.net/api/pokemons/1',
method: 'POST',
headers: {},
contentType: 'application/json',
timeout: 60,
sslClientProfile: 'webapi-sslcli-mgmt',
data: {"Message": "DataPower GatewayScript"}
};

Websocket server returned empty reply

I ran a websocket server using socket.io:
var http = require('http'),
fs = require('fs'),
// NEVER use a Sync function except at start-up!
index = fs.readFileSync(__dirname + '/index.html');
// Send index.html to all requests
var app = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(index);
});
// Socket.io server listens to our app
var io = require('socket.io').listen(app);
// Send current time to all connected clients
function sendTime() {
io.emit('time', { time: new Date().toJSON() });
}
// Send current time every 10 secs
setInterval(sendTime, 10000);
// Emit welcome message on connection
io.on('connection', function(socket) {
// Use socket to communicate with this particular client only, sending it it's own id
socket.emit('welcome', { message: 'Welcome!', id: socket.id });
socket.on('i am client', console.log);
});
app.listen(3000);
This server works fine withe a simple socket-io client:
var socket = require('socket.io-client')('http://127.0.0.1:1337');
socket.on('connect', function(){});
socket.on('time', function(data){console.log(data);});
socket.on('disconnect', function(){});
I tried to use cURL to send the connection request but it failed:
curl --verbose -i -N -H "Upgrade: websocket" -H "Connection: Upgrade" -H "Host: 127.0.0.1" -H "Origin: http://127.0.0.1" http://127.0.0.1:3000/
* Connected to 127.0.0.1 (127.0.0.1) port 3000 (#0)
> GET /socket.io HTTP/1.1
> User-Agent: curl/7.37.1
> Accept: */*
> Upgrade: websocket
> Connection: Upgrade
> Host: 127.0.0.1
> Origin: http://127.0.0.1
>
* Empty reply from server
* Connection #0 to host 127.0.0.1 left intact
curl: (52) Empty reply from server
If I removed the "Upgrade: websocket", then the server will send back the html page. The "Upgrade: websocket" is supposed to tell the server to upgrade the HTTP connection to websocket connection. Why it didn't work?

AngularsJS POST JSON data to Symfony2

I would like to know why this is not working , I have a AngularJS app witch sends trough AJAX data to a Symfony2 Application. As you can see, data is sent in my network console
<?php
namespace Supbox\CloudBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
class FolderController extends Controller
{
public function createAction(){
$post = $this->getRequest()->request;
$name = $post->get("name");
$folder = $post->get("folder");
var_dump($post);
die;
}
}
AngularJS code
$http({
method: 'POST',
url: route.folder.create,
data: {
folder: $scope.id,
name: name
}
})
Opera Network Console Output
Request URL:http://localhost/supbox/web/box/folder/create
Request Method:POST
Status Code:200 OK
Request Headersview source
Accept-Encoding:gzip,deflate,lzma,sdch
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Connection:keep-alive
Content-Length:25
Content-Type:application/json;charset=UTF-8
Host:localhost
Origin:http://localhost
Referer:http://localhost/supbox/web/box/
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36 OPR/20.0.1387.82
Request Payloadview source
{folder:1, name:Ang}
Response Headersview source
Connection:Keep-Alive
Content-Length:431
Content-Type:text/html
Date:Mon, 24 Mar 2014 13:25:53 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.4.4 (Win64) OpenSSL/1.0.1d PHP/5.4.12
X-Powered-By:PHP/5.4.12
If you (Angular JS) post data through header as JSON you need to change your code like this:
public function createAction(){
$post = $this->getRequest()->getContent();
$post = json_decode($post);
$name = $post->name;
$folder = $post->folder;
var_dump($post);
var_dump($name); // null
var_dump($folder); // null
die;
}
Dont know why, Angular $http sends data as request body, JSON encoded whereas Symfony2 is reading $_GET and $_POST arrays.
So you got 2 solutions:
1- Update Php code, you could override SF2 Request class (https://gist.github.com/ebuildy/fe1e708e466dc13dd736)
2- Update Js code, you can "transform" the $http request (https://gist.github.com/bennadel/11212050)
A bundle has been created to solve this problem, and it's very light.
qandidate-labs/symfony-json-request-transformer

WebSockets receive only "disconnect"

I'm trying this simple websocket example on Google Chrome:
var wsUri = "ws://echo.websocket.org/";
var output;
function init() {
output = document.getElementById("output");
testWebSocket();
}
function testWebSocket() {
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) {
onOpen(evt)
};
..............
..............
function onOpen(evt) {
writeToScreen("CONNECTED");
doSend("WebSocket rocks");
}
function onClose(evt) {
writeToScreen("DISCONNECTED");
}
window.addEventListener("load", init, false);
But i always receive only DISCONNECT!
There is something wrong?
Do I have to enable WebSockets protocol in my local Apache? If yes how to?
This server is not reliable. It even fails on their own demo page for Chrome 14.
The response for a WebSockets request of Chrome 14 is this, which is obviously not correct:
HTTP/1.1 200 OK
Server: Kaazing Gateway
Date: Tue, 27 Sep 2011 14:07:53 GMT
Content-Length: 0
Note that Chrome just switched to a new draft of the WebSockets protocol, which is a complete overhaul. This means that the server has to return a different handshake response and also has to decode messages that are sent, which was not the case with the previous draft. It might just be that they did not upgrade their server yet.
What you probably want is setting up your own server which is compliant with the new draft and test it on that server.
There are a lot of libraries for WebSockets servers popping up everywhere; you can have a look here and pick the server language of your choice.
You need to specify that websocket is a variable. Change this line:
websocket = new WebSocket(wsUri);
to this:
var websocket = new WebSocket(wsUri);
Hope it helps. This solved some problems for me.

Resources