example of extending Connection object in jsPlumb - jsplumb

Could anyone provide an example of extending/subclassing Connection object? The only bit of information I found in docs was:
getDefaultConnectionType
Returns the default Connection type. Used when someone wants to subclass Connection and have jsPlumb return instances of their subclass. you would make a call like this in your class’s constructor:
jsPlumb.getDefaultConnectionType().apply(this, arguments);
Returns
the default Connection function used by jsPlumb.
This sounds a little vague to me. Ideally I'd like to be able to use my subclass like this:
jsPlumb.addEndpoint(element, {
connector: ["MyConnector", { curviness: 65 }]
}
Thanks!

OK apparently I don't understand the difference between Connection and Connector, but anyways, extending Connection works fine like this:
var MyConnection = function (params) {
params.label = "bingo!";
jsPlumb.getDefaultConnectionType().apply(this, arguments);
};
jsPlumb.Defaults.ConnectionType = MyConnection;

Related

class instance wont save socket inside itself

Whenever a new user connects to socket.io an event handler will create a new class for that user called Events
const eventHandler = socket => {
new Events(socket);
};
and Events constructor will set its socket to the socket its been given upon creation
class Events {
constructor(socket) {
this.socket = socket;
this.socket.on('test', this.test)
}
test() {
console.log(this.socket); // logs undefined
}
}
the issue is why this.socket returns undefined? I think I'm missing how something in socket.io works, help is appreciated
I got my own answer, It actually has nothing to do with socket.io but rather how this works, further reading: How to access the correct `this` inside a callback?

How can I ensure the writable flag is true before send()?

I am creating an abstraction layer for Dart WebSocket who is also protocol compatible with Socket.IO, but it has a problem I can not solve.
The follow code convert the HttpRequest into a WebSocket and save the socket instance on the Transport... Here you can see I change the value of the writable flag to true in order to inform the socket is open.
WebSocketTransformer.upgrade(req).then((socket) {
this._socket = socket;
this.writable = true;
this._socket.handleError(() {
this.onClose();
});
// start listen the socket;
socket.listen((packet) {
this.onData(packet);
});
}).catchError((Exception e) {
this.onError('Can\'t conenct with the socket.', e.toString());
});
(The full code can be founded here.)
When I debug the code first the debugger stops inside that closure and only then stops here, where the check is make but writable still false :/
void flush([_]) {
if (this._readyState != SocketStates.closed && this.transport.writable &&
!this._writeBuffer.isEmpty) {
(The full code can be founded here)
I really need help...
Your constructor makes an async call but doesn't return a future (not possible in a constructor)
WebSocketTransformer.upgrade(req).then
Use a static method instead which returns Future<WebSocketTransformer> or use an init method where you initiaize your class after creation.
There might be other problems but yor code does not show how you use your class therefore its hard to tell.

Get room/rooms of client [duplicate]

I can get room's clients list with this code in socket.io 0.9.
io.sockets.clients(roomName)
How can I do this in socket.io 1.0?
Consider this rather more complete answer linked in a comment above on the question: https://stackoverflow.com/a/24425207/1449799
The clients in a room can be found at
io.nsps[yourNamespace].adapter.rooms[roomName]
This is an associative array with keys that are socket ids. In our case, we wanted to know the number of clients in a room, so we did Object.keys(io.nsps[yourNamespace].adapter.rooms[roomName]).length
In case you haven't seen/used namespaces (like this guy[me]), you can learn about them here http://socket.io/docs/rooms-and-namespaces/ (importantly: the default namespace is '/')
Updated (esp. for #Zettam):
checkout this repo to see this working: https://github.com/thegreatmichael/socket-io-clients
Using #ryan_Hdot link, I made a small temporary function in my code, which avoids maintaining a patch. Here it is :
function getClient(roomId) {
var res = [],
room = io.sockets.adapter.rooms[roomId];
if (room) {
for (var id in room) {
res.push(io.sockets.adapter.nsp.connected[id]);
}
}
return res;
}
If using a namespace :
function getClient (ns, id) {
return io.nsps[ns].adapter.rooms[id]
}
Which I use as a temporary fix for io.sockets.clients(roomId) which becomes findClientsSocketByRoomId(roomId).
EDIT :
Most of the time it is worth considering avoiding using this method if possible.
What I do now is that I usually put a client in it's own room (ie. in a room whose name is it's clientID). I found the code more readable that way, and I don't have to rely on this workaround anymore.
Also, I haven't tested this with a Redis adapter.
If you have to, also see this related question if you are using namespaces.
For those of you using namespaces I made a function too that can handle different namespaces. It's quite the same as the answer of nha.
function get_users_by_room(nsp, room) {
var users = []
for (var id in io.of(nsp).adapter.rooms[room]) {
users.push(io.of(nsp).adapter.nsp.connected[id]);
};
return users;
};
As of at least 1.4.5 nha’s method doesn’t work anymore either, and there is still no public api for getting clients in a room. Here is what works for me.
io.sockets.adapter.rooms[roomId] returns an object that has two properties, sockets, and length. The first is another object that has socketId’s for keys, and boolean’s as the values:
Room {
sockets:
{ '/#vQh0q0gVKgtLGIQGAAAB': true,
'/#p9Z7l6UeYwhBQkdoAAAD': true },
length: 2 }
So my code to get clients looks like this:
var sioRoom = io.sockets.adapter.rooms[roomId];
if( sioRoom ) {
Object.keys(sioRoom.sockets).forEach( function(socketId){
console.log("sioRoom client socket Id: " + socketId );
});
}
You can see this github pull request for discussion on the topic, however, it seems as though that functionality has been stripped from the 1.0 pre release candidate for SocketIO.

JsPlumb flowchart no self-connections

I have a problem where I'm more-or less using the jsPlumb flow-chart demo example but where there is only ever one drop target per window and there may be one or many drag targets. However I want to forbid self-connections so that a connection can be dragged from any window to any other window EXCEPT itself.
I was thinking that maybe you would use scopes but this would mean a different scope for each window which seems over the top. Does anyone have a tidy solution?
Thanks for the answers they pointed me in the right direction. In the end used "beforeDrop"
when binding the "connection" it was detaching the source endpoint of the window as well as the connection.
The final solution was:
instance.bind("beforeDrop", function (info) {
// console.log("before drop: " + info.sourceId + ", " + info.targetId);
if (info.sourceId === info.targetId) { //source and target ID's are same
console.log("source and target ID's are the same - self connections not allowed.")
return false;
} else {
return true;
}
});
from http://www.jsplumb.org/doc/connections.html#draganddrop
Preventing Loopback Connections
In vanilla jsPlumb only, you can instruct jsPlumb to prevent loopback connections without having to resort to a beforeDrop interceptor. You do this by setting allowLoopback:false on the parameters passed to the makeTarget method:
jsPlumb.makeTarget("foo", {
allowLoopback:false
});
Bind an event to get notified whenever new connection is created. After connection creation check whether source and target of connection are same, if so detach that connection to avoid self loop. Code:
jsPlumb.bind("jsPlumbConnection", function(ci) {
var s=ci.sourceId,c=ci.targetId;
if( s===c ){ //source and target ID's are same
jsPlumb.detach(ci.connection);
}
else{ // Keep connection if ID's are different (Do nothing)
// console.log(s+"->"+c);
}
});

Returning value from AJAX request in a global variable

Sorry if this question is duplicated but I couldn't solve my problem from other solutions.
I've got this code in a sepate file included in my main index:
var getSuggestedData = {
serviceURL: $("input[name=suggestedServices]").val(),
dataR:"",
doRequest:function(){
//request data to controller
$.ajax({
url:this.serviceURL,
success:function(msg){
this.dataR = msg;
}
})
}
}
When I'm trying to get the variable "dataR" from my index this way it's UNDEFINED! PLEASE, can someone help me out?
$().ready(function() {
getSuggestedData.doRequest();
alert(getSuggestedData.dataR);
});
Thank you in advance!
The reason you are not able to access the dataR object is because it is not in the same context as the result returned from the success method.
One technique is to hold a reference to this in a variable as shown below:
var self = this;
using the jquery library!
$(this.button).bind('click',{self:this},function(event)
{
var that = event.data.self;
alert(that.num);
});
You can also check out the post below in which I explained in detailed about the "this" keyword.
http://azamsharp.com/Posts/57_I_mean__this__not__this_.aspx
If memory serves me right...
this.dataR = msg;
probably needs to be
getSuggestedData.dataR = msg
the 'this' reference would be to the object fed to jQuery, you need to reference the original object. I forget if you could access it by its name directly such as this or if you need to use another method, let me know if it doesn't work out though.

Resources