I've been struggling to figure out how I'm meant to configure MassTransit and our new dedicated cloudamqp instance to work with SSL (note:everything is working without SSL fine).
I tried adding the UseSsl line in the code below, which I found in some old documentation, but that didn't work:
var bus = Bus.Factory.CreateUsingRabbitMq(sbc =>
{
var host = sbc.Host(new Uri(messageBusConfiguration["Host"]), h =>
{
h.Username(messageBusConfiguration["Username"]);
h.Password(messageBusConfiguration["Password"]);
h.UseSsl(s => {});
});
});
In cloudamqp I've set it to allow ampqs too and my services/APIs are setup and running in IIS using HTTPs without any issues.
I suspect I'm missing something fundamental here but I can't find any documentation on it.
This works for me, note that the port must be specified.
var busControl = Bus.Factory.CreateUsingRabbitMq(x =>
{
var host = x.Host(new Uri("rabbitmq://wombat.rmq.cloudamqp.com:5671/your_vhost/"), h =>
{
h.Username("your_username");
h.Password("your_password");
h.UseSsl(s =>
{
s.Protocol = SslProtocols.Tls12;
});
});
x.ReceiveEndpoint(host, "input_queue", e =>
{
});
});
await busControl.StartAsync(new CancellationTokenSource(TimeSpan.FromSeconds(30)).Token);
await busControl.StopAsync();
Related
I'm trying to use the websocket example from:
https://github.com/alpacahq/alpaca-trade-api-js/blob/master/examples/websocket_example_datav2.js
In order to connect to the Alpaca V2 data stream. Currently, my stream is working but I'm trying to route my data to the client side using Server Sent Events. My data flow seems like it should be:
Alpaca Data Stream API -> My Node.js server -> React Frontend.
The issue I have is using the DataStream object in the example in order to route the data to the frontend. Since, with the object alone, I don't have any route to subscribe to via Server Sent Events, does this mean that I should also be using either express, socket.io, or ws? Since the all of the ".on_xyz" methods are defined within the DataStream object, I'm not sure how to set up the endpoint properly to allow my frontend to subscribe to it. If anyone knows how to route this datastream information forward it would be greatly appreciated- I'm particularly trying to work with the .onStockQuote method but any of them is fine! I'm simply trying to use Node as an inbetween router so that I don't have to subscribe directly from the frontend (and not use the sdk), because that limits scalability of the API's use.
"use strict";
/**
* This examples shows how to use tha alpaca data v2 websocket to subscribe to events.
* You should use the alpaca api's data_steam_v2, also add feed besides the other parameters.
* For subscribing (and unsubscribing) to trades, quotes and bars you should call
* a function for each like below.
*/
import express from 'express';
const app = express()
const Alpaca = require("#alpacahq/alpaca-trade-api");
const API_KEY = "XYZ_Key";
const API_SECRET = "XYZ_Secret";
const PORT = 3000;
// Add a new message and send it to all subscribed clients
const addMessage = (req, res) => {
const message = req.body;
// Return the message as a response for the "/message" call
res.json(message);
return ;
};
class DataStream {
constructor({ apiKey, secretKey, feed }) {
this.alpaca = new Alpaca({
keyId: apiKey,
secretKey,
feed,
});
const socket = this.alpaca.data_stream_v2;
socket.onConnect(function () {
console.log("Connected");
socket.subscribeForQuotes(["AAPL"]);
// socket.subscribeForTrades(["FB"]);
// socket.subscribeForBars(["SPY"]);
// socket.subscribeForStatuses(["*"]);
});
socket.onError((err) => {
console.log(err);
});
socket.onStockTrade((trade) => {
console.log(trade);
});
socket.onStockQuote((quote) => {
console.log(quote);
});
socket.onStockBar((bar) => {
console.log(bar);
});
socket.onStatuses((s) => {
console.log(s);
});
socket.onStateChange((state) => {
console.log(state);
});
socket.onDisconnect(() => {
console.log("Disconnected");
});
socket.connect();
// unsubscribe from FB after a second
// setTimeout(() => {
// socket.unsubscribeFromTrades(["FB"]);
// }, 1000);
}
}
app.post("/message", addMessage);
let stream = new DataStream({
apiKey: API_KEY,
secretKey: API_SECRET,
feed: "sip",
paper: false,
});
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}`);
});
I have implemented cloudflare on a live website, the website has a socket server that's setup with socket.io and express, everything were working fine before implementing cloudflare
Currently I'm using port: 2053 which i've allowed access to through Laravel forge
socket.js
var app = require('express')();
const fs = require('fs');
var server = require('https').createServer({
key: fs.readFileSync('/etc/nginx/ssl/mywebsite.com/1234/server.key'),
cert: fs.readFileSync('/etc/nginx/ssl/mywebsite.com/1234/server.crt'),
}, app);
var io = require('socket.io')(server, {
cors: {
origin: function(origin, fn) {
if (origin === "http://mywebsite.test" || origin === "https://mywebsite.com") {
return fn(null, origin);
}
return fn('Error Invalid domain');
},
methods: ['GET', 'POST'],
'reconnect': true
},
});
var Redis = require('ioredis');
var redis = new Redis();
redis.subscribe('asset-channel', () => {
console.log('asset-channel: started');
});
redis.on('message', function(channel, message) {
var message = JSON.parse(message);
io.to(message.data.id).emit(channel + ':' +message.event + ':'+ message.data.id, message.data);
});
io.on("connection", (socket) => {
socket.on("join:", (data) => {
socket.join(data.id);
});
socket.on("leave:", (data) => {
socket.leave(data.id);
});
});
server.listen(2053, () => {
console.log('Server is running!');
});
app.js
if (! window.hasOwnProperty('io')) {
// if (
// window.origin === "http://mywebsite.test" ||
// window.origin === "https://mywebsite.com" ||
// window.origin == "https://mywebsite.test"
// ) {
window.io = io.connect(`${window.origin}:2053`);
window.io.on('connection');
// }
}
As mentioned before everything were working fine before implementing cloudflare and i have tried to read some different documentation like:
https://developers.cloudflare.com/cloudflare-one/policies/zero-trust/cors
https://socket.io/docs/v4/handling-cors/
I found many different problems similar online, and tried several solutions but nothing seem to make the socket connection work
Tried to allow all cors like so:
var io = require('socket.io')(server, {
cors: {
origin: "*",
methods: ['GET', 'POST'],
'reconnect': true
},
});
Didn't work either, tried configure some stuff in nginx which didn't work either
Error
Access to XMLHttpRequest at 'https://mywebsite.com:2053/socket.io/?EIO=4&transport=polling&t=NurmHmi' from origin 'https://mywebsite.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I think i might have to configure something in the cloudflare dashboard, i just dont know what and my googling skills could not take me to the finish line this time around.
Im not too experienced with sockets so it would be awesome if there are some skilled socket expert who have had this issue before who can guide me in the correct direction? :)
I made it run by adding this to the app.js:
window.io = io.connect(`${window.origin}:2053`, { transports: ["websocket"] });
Apparently it will try to use polling instead of websocket.
I have a webRTC implementation working, but it requires a setup function to be run on page load.
setup = () => {
peerConnection = new RTCPeerConnection(servers)
peerConnection.onicecandidate = onicecandidate
peerConnection.onconnectionstatechange = onconnectionstatechange(
peerConnection,
)
peerConnection.onnegotiationneeded = onnegotiationneeded
peerConnection.ontrack = function({streams: [stream]}) {
const remoteVideo = document.getElementById('remote-video')
if (remoteVideo) {
remoteVideo.srcObject = stream
}
}
mediaStream.getTracks().forEach(track => peerConnection.addTrack(track, mediaStream))
}
Only then can I make the offer:
makeOffer = () => {
peerConnection
.createOffer()
.then(offer => {
return peerConnection
.setLocalDescription(new RTCSessionDescription(offer))
.then(() => offer)
})
.then(offer => {
sendOffer(offer)
})
}
If i attempt to run the setup just prior to the makeOffer function I get the error:
DOMException: Failed to execute 'setLocalDescription' on
'RTCPeerConnection': Failed to set local offer sdp: The order of
m-lines in subsequent offer doesn't match order from previous
offer/answer.
My assumption is that it is due to the makeOffer running before something in the setup has completed, but nothing in the setup seems to be asynchronous. What do I need to do to be able to setup the connection and send the offer all at once?
I have a question about MassTransit configuration.
There is a Main application and Microservice.
For example, the Main application sends a commands to the microservice(consumer) to write off funds from the account.
Configuration in the Main application:
var rabbitHost = new Uri("rabbitmq://localhost/app");
services.AddMassTransit(x => {
x.AddBus(provider => Bus.Factory.CreateUsingRabbitMq(cfg => {
var host = cfg.Host(rabbitHost, hostConfigurator => {
hostConfigurator.Username("user");
hostConfigurator.Password("password");
});
}));
});
EndpointConvention.Map<WithdrawFunds>(new Uri(rabbitHost + "/test-queue"));
Microservice configuration:
var rabbitHost = new Uri("rabbitmq://localhost/app");
services.AddMassTransit(x => {
x.AddBus(provider => Bus.Factory.CreateUsingRabbitMq(cfg => {
var host = cfg.Host(rabbitHost, hostConfigurator => {
hostConfigurator.Username("username");
hostConfigurator.Password("password");
});
cfg.ReceiveEndpoint(host, "test-queue", ep => {
ep.Consumer<WithdrawFundsConsumer>();
});
}));
});
Command executed in Main application like:
await _sendEndpointProvider.Send<WithdrawFunds>(new {
Amount = 100,
AccountId = "someId"
});
MassTransit creates a "test-queue" queue and if both applications are running, then the interaction works successfully. But if I stop the microservice, then a
"test-queue_skipped" queue is created in which the missed messages fall. However, if I start the Microservice, it will not receive missed messages.
How can I configure MassTransit so that "_skipped" is not created, and messages are waiting for the consumer to appear?
In my nodejs application, i am using socket.io for sockets connection.
I am configuring my server side code like this
socket.io configuration in separate file.
//socket_io.js
var socket_io = require('socket.io');
var io = socket_io();
var socketApi = {};
socketApi.io = io;
module.exports = socketApi;
below is my server.js file in which i am attaching my socket io to the server like this
var socketApi = require('./server/socket_io');
// Create HTTP server.
const server = http.createServer(app);
// Attach Socket IO
var io = socketApi.io;
io.attach(server);
// Listen on provided port, on all network interfaces.
server.listen(port, () => console.log(`API running on localhost:${port}`));
and then i am using socket.io in my game.js file to emit updated user coins like this.
//game.js
var socketIO = require('../socket_io');
function updateUserCoins(userBet) {
userId = mongoose.Types.ObjectId(userBet.user);
User.findUserWithId(userId).then((user) => {
user.coins = user.coins - userBet.betAmount;
user.save((err, updatedUser) => {
socketIO.io.sockets.emit('user coins', {
userCoins: updatedUser.coins,
});
});
})
}
and then in my client side, i am doing something like this,
socket.on('user coins', (data) => {
this.coins = data.userCoins;
});
but with the above implementation, updating coins of any user, updates all user coins at the client side, since all the clients are listening to the same socket user coins.
To solve the above problem, i know that i have to do something like this,
// sending to individual socketid (private message)
socketIO.io.sockets.to(<socketid>).emit('user coins', {
userCoins: updatedUser.coins,
});
but my concern is that how will get <socketid> with my current implementation.
You can get it by listening to connection to your socket.io server :
io.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Here you have a socket object ( io.on('connection', function (socket) ) and you can get his id with socket.id
So you'll probably need to wrap your code with the connection listener.
Source of the exemple for the connection listener
Socket object description