Unable to establish Handshake with Public Websocket API for Kraken - javascript

I'm trying to make a watchlist for cryptocurrency tickers You type a ticker, add it, and it will show you real time prices in a table format.
My first step is to try and establish a handshake connection with the Kraken websocket API (documentation here: https://www.kraken.com/features/websocket-api#connectionDetails)
My ask:
At the moment, all I want to do is be able to console log a "connection success" for when I'm connected with the websocket API from Kraken (crypto exchange). I'm trying to do this via the portion below (scroll all the way down to see all of the code)
socket.onopen = function(event) {
socketStatus.innerHTML = 'Connected to: ' + event.currentTarget.url;
socketStatus.className = 'open';
};
I've got an index.html file, and an app.js file. When I open the index.html file in chrome, I get an error:
app.js:5 WebSocket connection to 'ws://ws-sandbox.kraken.com/' failed: Error during WebSocket handshake: Unexpected response code: 521
I've tried with only this line of code for websocket related stuff
var socket = new WebSocket('ws://ws-sandbox.kraken.com')
I've also tried to use the get method, provided in examples from here
https://medium.freecodecamp.org/here-is-the-most-popular-ways-to-make-an-http-request-in-javascript-954ce8c95aaa
$.get('ws://ws-sandbox.kraken.com',function(data){console.log(`${data}`)})
in my app.js file, my question is, apart from line below what else do I need to successfully do the handshake? Do I need to send a GET request with header information (please see very end)?
var socket = new WebSocket('ws://ws-sandbox.kraken.com')
in the documentation, you'll see connection details. Connection details for sandbox environment. The URL is ws-sandbox.kraken.com
link: https://www.kraken.com/features/websocket-api#connectionDetails
I've followed the example here:
https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
GET REQUEST QUESTION:
I was looking at this site as an example:
https://blog.teamtreehouse.com/an-introduction-to-websockets
and it said I need to send an HTTP request to the server using something similar to this. I'm just not sure if this is required for what I'm trying to do.
GET ws://websocket.example.com/ HTTP/1.1
Origin: http://example.com
Connection: Upgrade
Host: websocket.example.com
Upgrade: websocket
CODE IN APP.JS FILE
$(document).ready(function(){ console.log('page ready')
var socket = new WebSocket('ws://ws-sandbox.kraken.com')
$.get('ws://ws-sandbox.kraken.com',function(data){console.log(`${data}`)})
var form = document.getElementById('message-form');
var messageField = document.getElementById('message');
var messagesList = document.getElementById('messages');
var socketStatus = document.getElementById('status');
var closeBtn = document.getElementById('close');
socket.onopen = function(event) { //LOGGING SUCCESSFUL CONNECTION HERE
socketStatus.innerHTML = 'Connected to: ' + event.currentTarget.url;
socketStatus.className = 'open';
};
})

I know this is an old question but I was having the same issue and wanted to provide my solution in case anyone else comes here in need of it.
So the reason I found for this error was because I using a protocol that was not supported by the API. I was using TLS 1.0 where the Kraken API only supports 1.2/1.3:
https://support.kraken.com/hc/en-us/articles/360023264371-TLS-upgrade-that-might-affect-your-API-connections
So to solve it, I simply set my websocket client to use TLS 1.2 as the protocol.

From a browser, using the Websocket() built-in api:
new WebSocket("wss://ws.kraken.com").onopen = function(){
this.onclose = () => console.log("SOCKET CLOSED")
this.onmessage = (e) => console.log(JSON.parse(e.data))
this.send(JSON.stringify({
"event": "subscribe",
"pair": ["XBT/USD"],
"subscription": {
"interval": 1,
"name": "ohlc"
}
}), (e) => console.log(e))
}

Related

Javascript websocket not connecting

I'm trying to make a simple chat application
I have a server made with Spring running with a websocket
I've also made an android app that successfully connects to the websocket and receives and sends messages
To make testing easier I decided to make a web client for the server in html/js, but the websocket connection fails
I'm using the exact same address as I am in the android app
Heres my JS code:
$( document ). ready(function(){
var ws = new WebSocket("ws://192.168.1.3:8080/chatwebsocket")
ws.onmessage = function (event) {
var msg = event.data
$("#chat_container").append(`<p>$(msg.sender): $(msg.content))</p>`)
}
ws.onerror = function (event) {
console.log('WebSocket error: ', event);
}
ws.onclose = function (event) {
console.log('WebSocket closed: ', event);
}
$("#message_form").onsubmit = function(data) {
var msgContent = data.messageContent
var msg = {"sender":"webclient", "content": msgContent}
ws.send(JSON.stringify(msg))
}
})
I've tested it with Chrome and Firefox and both fail
Chrome just gives the message: WebSocket connection to 'ws://192.168.1.3:8080/chatwebsocket' failed:
Theres no useful info in either the error or close events
No connection is made on the server side
The web client successfully connects to wss://ws.postman-echo.com/raw for an example
Can someone please point me in the right direction with troubleshooting this because I feel like I have no info to work with

php ZMQ push integration over http

Im am trying to implement push integration using php and native zmq. I have successfully send send my message to server, but my problem is I cannot push the message to browser using js Websocket(). I says WebSocket connection to 'ws://127.0.0.1:8080/' failed: Error during WebSocket handshake: Invalid status line
here is my code for client:
<?php
try {
function send($data) {
$context = new ZMQContext();
$push = new ZMQSocket($context, ZMQ::SOCKET_PUSH);
$push->connect("tcp://localhost:5555");
$push->send($data);
}
if(isset($_POST["username"])) {
$envelope = array(
"from" => "client",
"to" => "owner",
"msg" => $_POST["username"]
);
send(json_encode($envelope)); # send the data to server
}
}
catch( Exception $e ) {
echo $e->getMessage();
}
?>
Client
here is my server:
$context = new ZMQContext();
$pull = new ZMQSocket($context, ZMQ::SOCKET_PULL);
$pull->bind("tcp://*:5555"); #this will be my pull socket from client
$push = new ZMQSocket($context, ZMQ::SOCKET_PUSH);
$push->bind("tcp://127.0.0.1:8080"); # this will be the push socket to owner
while(true) {
$data = $pull->recv(); # when I receive the data decode it
$parse_data = json_decode($parse_data);
if($parse_data["to"] == "owner") {
$push->send($parse_data["msg"]); # forward the data to the owner
}
printf("Recieve: %s.\n", $data);
}
and here is my owner.php i'm expecting the data to be send thru Websocket in browser:
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h2>Message</h2>
<ul id="messagelog">
</ul>
<script>
var logger = document.getElementById("messagelog");
var conn = new WebSocket("ws://127.0.0.1:8080"); # the error is pointing here.
conn.onOpen = function(e) {
console.log("connection established");
}
conn.onMessage = function(data) {
console.log("recieved: ", data);
}
conn.onError = function(e) {
console.log("connection error:", e);
}
conn.onClose = function(e) {
console.log("connection closed~");
}
</script>
</body>
Please do tell me what I am missing. thank you.
You didn't establish a protocol communication at all. You managed to receive the message, but you never confirmed, by parsing it and sending appropriate response, that your server is indeed a WebSocket server.
Since you are already using PHP and ZeroMQ, the easiest way out is to use Mongrel2 which is, among other things, capable of understanding WebSocket protocol and deliver it to a ZeroMQ endpoint encoded as a tnetstring (a json-like encoding format, trivial to parse).
The other solution is to fully support the WebSocket protocol in your code - something that's outside of the scope of this question and answer.
You cannot connect a websocket to a zmq socket*, they are different communication protocols (a websocket is more like a traditional socket, a zmq socket is more of an abstraction that adds extra features). You need to set up a way on your server to receive a websocket connection.
*You may be able to make this work using RAW socket types, but that's a bit more advanced and shouldn't be entered into unless you know what you're doing.

javascript: print websocket client IP

node.js WebSocket example code snippet
I have a simple node.js application using express. Now everytime a client connects to the node server I see the string 'new client connected' but I would like to know which IP the new client had.
var WebSocketServer = require('ws').Server;
var connIds = [];
var server = require('http').createServer(app).listen(80);
// set up the websocket server
var wss = new WebSocketServer( { server: server } );
wss.clientConnections = {};
// websocket server eventlisteners and callbacks
wss.on('connection', function (connection) {
console.log('wss.on.connection - new client connected');
...
See the code at:
https://github.com/qknight/relais.js/blob/master/relais.js/server.js#L159
question
The object connection has properties but I don't understand how to query them or what they are. All I want is to print the client IP and maybe, if existent, other similar properties as well.
How do I do that?
Remote IP is a property of the pre-upgrade connection:
var wss = new WebSocketServer({port: 9876});
wss.on('connection', function(ws) {
console.log(ws.upgradeReq.connection.remoteAddress);
});
i don't recall how i found it, but i know it took me a while; i wish the docs were as good as the code...
UPDATE:
WS has moved some things around, so here's an updated example of how to get the original HTTP info in current code. Note the 2nd argument to the connection event handler:
wss.on('connection', function conn(ws, req) {
var ip = req.connection.remoteAddress;
console.info(ip);
});

netty secure websockets using http.. possible?

I have configured my websocket connection following the example:
https://github.com/netty/netty/tree/3/src/main/java/org/jboss/netty/example/http/websocketx/sslserver
This all works, i have the browser connecting to a secured websocket using https address.
$(document).ready(function () {
var location = "wss://localhost:9999/websocket"
ws = new WebSocket(location);
ws.onopen = function(event) {
}
ws.onclose = function(event) {
}
ws.onmessage = function(event) {
}
});
I want to connect to this page that makes the websocket connection using http?... is that possible ?... I have tried this, and it doesn't seem to work.. so im not sure...
I have read that it is possible to create a WSS connection when regardless of going to the page using http or https?.. is this correct?

nodejs + WebSockets - reject the connection with a message

I want to provide a meaningful error to the client when too many users are connected or when they're connecting from an unsupported domain, so...
I wrote some WebSocket server code:
var http = require('http');
var httpServer = http.createServer(function (request, response)
{
// i see this if i hit http://localhost:8001/
response.end('go away');
});
httpServer.listen(8001);
// https://github.com/Worlize/WebSocket-Node/wiki/Documentation
var webSocket = require('websocket');
var webSocketServer = new webSocket.server({ 'httpServer': httpServer });
webSocketServer.on('request', function (request)
{
var connection = request.reject(102, 'gtfo');
});
And some WebSocket client code:
var connection = new WebSocket('ws://127.0.0.1:8001');
connection.onopen = function (openEvent)
{
alert('onopen');
console.log(openEvent);
};
connection.onclose = function (closeEvent)
{
alert('onclose');
console.log(closeEvent);
}
connection.onerror = function (errorEvent)
{
alert('onerror');
console.log(errorEvent);
};
connection.onmessage = function (messageEvent)
{
alert('onmessage');
console.log(messageEvent);
};
All I get is alert('onclose'); with a CloseEvent object logged to the console without any status code or message that I can find. When I connect via ws://localhost:8001 the httpServer callback doesn't come into play, so I can't catch it there. The RFC suggests I should be able to send any status code other than 101 when there's a problem, but Chrome throws an error in the console Unexpected response code: 102. If I call request.reject(101, 'gtfo'), implying it was successful I get a handshake error, as I'd expect.
Not really sure what else I can do. Is it just not possible right now to get the server response in Chrome's WebSocket implementation?
ETA: Here's a really nasty hack in the mean time, I hope that's not what I have to end up doing.
var connection = request.accept(null, request.origin);
connection.sendUTF('gtfo');
connection.close();
I'm the author of WebSocket-Node and I've also posted this response to the corresponding issue on GitHub: https://github.com/Worlize/WebSocket-Node/issues/46
Unfortunately, the WebSocket protocol does not provide any specific mechanism for providing a close code or reason at this stage when rejecting a client connection. The rejection is in the form of an HTTP response with an HTTP status of something like 40x or 50x. The spec allows for this but does not define a specific way that the client should attempt to divine any specific error messaging from such a response.
In reality, connections should be rejected at this stage only when you are rejecting a user from a disallowed origin (i.e. someone from another website is trying to connect users to your websocket server without permission) or when a user otherwise does not have permission to connect (i.e. they are not logged in). The latter case should be handled by other code on your site: a user should not be able to attempt to connect the websocket connection if they are not logged in.
The code and reason that WebSocket-Node allow you to specify here are an HTTP Status code (e.g. 404, 500, etc.) and a reason to include as a non-standard "X-WebSocket-Reject-Reason" HTTP header in the response. It is mostly useful when analyzing the connection with a packet sniffer, such as WireShark. No browser has any facility for providing rejection codes or reasons to the client-side JavaScript code when a connection is rejected in this way, because it's not provided for in the WebSocket specification.

Categories