Detect when a socket io connection has been changed with ember - javascript

Im using ember with socket.io and I want a computed property that changes to if the socket io connection is connected or disconnected.
I am using ember-websockets and here is what I have tried:
socketIOService: service('socket-io'),
socketRoute: 'http://localhost:8080/',
connected: computed('socketIOService',
function()
{
console.log('changed!');
//return (this.get('socketIOService').socketFor(this.get('socketRoute').socket.connected));
}),
startConnection()
{
this.get('connected');
const socket = this.socketIOService.socketFor(this.get('socketRoute'));
socket.on('initialised', this.initialised, this);
},
So this doesnt work because im guessing the service doesnt change. I would like to be able to computer a value from the following...
this.socketIOService.socketFor(this.get('socketRoute'));
But I cant get the sockerFor property in a computed property.

Looking at readme, I think you can use 'open' and 'close' events, w/co computed properties:
startConnection()
{
const socket = this.socketIOService.socketFor(this.get('socketRoute'));
socket.on('open', () => { this.set('connected', true); });
socket.on('close', () => { this.set('connected', false); });
}

Related

Socket.io a particular event emit is not working

I have backend in nodejs and frontend in Reactjs, I am using socket.io for live event handling, everything works fine apart from one thing. I am attaching my server and client code snippets here :
server.js
socket.on("joinroom", ({ roomid, username }, callback) => {
console.log("student joined room", username);
socket.join(roomid);
socket.to(roomid).emit("newstudentcount");
socket.to(roomid).emit("scoreupdate");
socket.to(roomid).emit("info", { username, roomid });
});
and for client react application:
componentDidMount() {
socket = io("http://127.0.0.1:5000");
socket.emit("joinroom", {
username: this.props.userData.username,
roomid: this.props.roomInfo.roomid,
});
socket.on("scoreupdate", () => {
console.log("order to get score")
this.getMyScore();
})
socket.on("newpuzzle", ({ config, min, sec }) => {
console.log("TEACHER GAVE ME NEW PUZZLE");
console.log(config, min, sec);
this.setState({
puzConfig: config,
time: this.calculateSeconds(min,sec),
totalTIme: this.calculateSeconds(min,sec),
isPuzAssign: true,
});
this.startTimer();
});
}
every other event emits work fine apart from scoreupdate event. Now I am not sure what is wrong here, either the client is unable to read the event or the server is not emitting the event. In either case, I don't see any issue in this code.
Things I have already tried:
changing event name
changing sequence of events
removing other events apart from scoreupdate.
Nothing works.
It would be great if someone could help.

Laravel Event Broadcast not being picked up laravel-echo-server

I'm attempting to use laravel-echo-server (socket.io) I'm getting a roadblock where the client-side doesn't appear to be getting any broadcasted events.
Everything seems to be connected fine and socket.io server is reporting that it's connecting and authorising the user however when I broadcast a message nothing seems to happen. The event is appearing on Laravel Horizon but otherwise, nothing happens. Here is my code:
server.js to run the laravel-echo-server:
require('dotenv').config();
const env = process.env;
require('laravel-echo-server').run({
authHost: env.APP_URL,
devMode: env.APP_DEBUG,
database: "redis",
databaseConfig: {
redis: {
host: env.REDIS_HOST_PUBLIC,
port: env.REDIS_PORT,
}
}
});
My channel in channel.php
Broadcast::channel('message.pushed', function () {
return true;
});
My event:
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class MessagePushed implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct()
{
$this->message = "My New Message";
}
/**
* Get the channels the event should broadcast on.
*
* #return Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('message.pushed');
}
}
My event listener within app.js
import Echo from 'laravel-echo';
window.io = require('socket.io-client');
if (typeof io !== 'undefined') {
var token = $('meta[name="_token"]').attr('content')
window.Echo = new Echo({
auth : {
headers: {
Authorization: `Bearer ${token}`,
},
},
broadcaster: 'socket.io',
host : window.location.hostname + ':6001',
});
}
function listenForBroadcast() {
Echo.private('message.pushed')
.listen('MessagePushed', (e) => {
console.log(e)
console.log("Listened")
});
}
listenForBroadcast();
Lastly the route sending the message:
Route::get('/event-test', function () {
broadcast(new App\Events\MessagePushed());
});
I am not quite sure where i have gone wrong or why nothing is being picked up by the client.
While looking in laravel-echo-server the command line is echoing:
Channel: laravel_database_private-message.pushed
Event: App\Events\MessagePushed
In you browser you need to listen on Channel as shown by redis and also listen to the event as shown by redis, so changing your listenForBroadcast() method may help.
In the code, Channel name changed from message.pushed to laravel_database_private-message.pushed and Event name changed from MessagePushed to .App\Events\MessagePushed ( Do not miss dot prefix to App )
function listenForBroadcast() {
Echo.private('laravel_database_private-message.pushed')
.listen('.App\\Events\\MessagePushed', (e) => {
console.log(e)
console.log("Listened")
});
}
I tried this solution based on the solution given in the following link and it worked for me
laravel Echo does not listen to channel and events

Using Pusher with SimpleWebRTC

I've come across the SimpleWebRTC package. Trying to get it to work, but can't seem to get the remote stream coming through. I'm also using Pusher for signalling, rather than the default that comes with SimpleWebRTC.
I've set up my own connection:
var myConnection = {
pusher: new Pusher('mypusherkey', { cluster: 'ap1' } ),
channel: null,
on: function (event, callback) {
this.pusher.bind (event, callback);
},
emit: function () {
if (arguments.length == 1) {
if (arguments[0] === "join") {
this.channel = this.pusher.subscribe(arguments[1]);
}
}
else
this.channel.trigger(arguments);
},
getSessionId: function() {
return this.pusher.connection.socket_id;
},
disconnect: function() {
this.pusher.disconnect();
}
};
Then I have the SimpleWebRTC initialisation:
var webrtc = new SimpleWebRTC({
// the id/element dom element that will hold "our" video
localVideoEl: 'localVideo',
// the id/element dom element that will hold remote videos
remoteVideosEl: 'remotesVideos',
// immediately ask for camera access
autoRequestMedia: true,
debug: true,
connection: myConnection
});
// we have to wait until it's ready
webrtc.on('readyToCall', function () {
console.log('ready to join');
// you can name it anything
webrtc.joinRoom('test-video-chat');
});
Doing a simple test between 2 PCs, it's not setting up the remote stream. In the dev console apart from the intitial event hook ups, I'm not seeing any other activity happening, especially SimpleWebRTC "readyToCall" not firing.
you probably need to emit a 'connect' signal from your socket adapter to trigger this code

socket.io Expanding the original client js library

This is my original client code
var socket = io.connect('http://localhost:7048');
socket.on('channel', function (mess) {
console.log(mess);
});
socket.on('message', function (mess) {
console.log(mess);
});
How can I extend the original library so that you get something like this. Such code is used by pubnub.
var myPlugin = MYPLUGIN({
host: 'http://localhost:7048'
});
myPlugin.listen({
channel: 'channel',
message: function(m){console.log(m)},
error: function(m){console.log(m)}
});
myPlugin.listen({
channel: 'message',
message: function(m){console.log(m)},
error: function(m){console.log(m)}
});
myPlugin.unlisten({
channel : 'message',
});
If you're trying to make it like the code on pubnub just because pubnub uses this kind of syntax and you're used to it, I don't recommend on doing it, but if you have an API and you need to have a certain architecture then that's fine.
I recommend building a wrapper.
function MyPlugin(hostObj) {
function listen(listenObj) {
//your code here
}
function unlisten(unlistenObj) {
//your code here
}
//this makes your functions public
Object.defineProperties(this, {
"listen": {value: listen},
"unlisten": {value: unlisten}
});
return this;
}

Iron-Router randomly returning undefined in Meteor

For some odd reason, iron-router randomly returns undefined.
this.route('pollyShow', {
path: '/polly/:_id',
template: 'polly_show',
notFoundTemplate: 'notFound',
before: function () {
var id = this.params._id;
var poll = Polls.findOne({_id: id});
console.log(poll);
var ip_array = poll.already_voted;
$.getJSON("http://smart-ip.net/geoip-json?callback=?", function(data){
ip_voted = ip_array.indexOf(data.host);
if (ip_voted > -1) {
Router.go('pollyResults', {_id: id});
}
});
},
data: function() {
return Polls.findOne({_id: this.params._id});
}
});
Sometimes it is returning normally while other times it just returns undefined.
Is there any reason behind this?
The problem occurs because the Polly collection is sometimes populated and at other times unpopulated when the route executes.
This problem can be prevented by explicitly waiting on a subscription using waitOn option in the route configuration.
From the docs:
By default, a new Meteor app includes the autopublish and insecure packages, which together mimic the effect of each client having full read/write access to the server's database. These are useful prototyping tools, but typically not appropriate for production applications. When you're ready, just remove the packages.
To remove the packages, call meteor remove <package-name>.
Then you need to explicitly publish records which you want to see on the client on the server:
server/publications.js:
Meteor.publish('all_of_polly', function () { return Polls.find({}); });
And subscribe to it on the client:
this.route('pollyShow', {
path: '/polly/:_id',
template: 'polly_show',
notFoundTemplate: 'notFound',
waitOn: function () { return Meteor.subscribe('all_of_polly'); }
// ...
});

Categories