We have a Stencil web component that renders a user dialog. It consists of an "outerComponent" and an "innerComponent".
The outer one cares about dealing with the browser (props, load stuff from cookies etc.) and the inner one renders the actual HTML and lets the user operate it.
(Actually there are more components used inside, from a different project for the UI components such as checkbox, button etc. But I don't think that's relevant here.)
When a checkbox, button etc. is clicked in <inner-component> an onclick-handler within the component is called that executes some UI logic (e.g. set the "checked" property) and then emits a custom event, e.g.:
#Event() checkboxToggleModalEvent: EventEmitter<OptionType>;
...
<checkbox-comp fid="...">
<input type="checkbox" checked={optionCheckbox.userSelection} onClick={this.handleCheckbox} />
...
</checkbox-comp>
...
private handleCheckbox(event: Event) {
const checkboxElement: HTMLInputElement = event.target as HTMLInputElement;
...
const selection: OptionType = { name: indexId, userSelection };
this.checkboxToggleModalEvent.emit(selection);
}
Now, in <outer-component> this event is listened for and the handler cares for the "technical" logic:
#Listen("checkboxToggleModalEvent")
checkboxToggleModalEventHandler(event) {
LogService.log.debug(event);
... some technical logic
}
This works fine in most cases. Now we have an integration on one site, where the events apparently do not get emitted correctly or somehow lost in the middle.
The UI logic is executed normally but the handler in outerComponent never gets called.
I was able to find the piece of code from an integrated library that causes the problem (sorry for pasting the whole function!):
// From the imported library on customer website:
function(t, exports) {
try {
var e = new window.CustomEvent("test");
if (e.preventDefault(),
!0 !== e.defaultPrevented)
throw new Error("Could not prevent default")
} catch (t) {
var n = function(t, e) {
var n, r;
return e = e || {
bubbles: !1,
cancelable: !1,
detail: void 0
},
n = document.createEvent("CustomEvent"),
n.initCustomEvent(t, e.bubbles, e.cancelable, e.detail),
r = n.preventDefault,
n.preventDefault = function() {
r.call(this);
try {
Object.defineProperty(this, "defaultPrevented", {
get: function() {
return !0
}
})
} catch (t) {
this.defaultPrevented = !0
}
}
,
n
};
n.prototype = window.Event.prototype,
window.CustomEvent = n
}
}
If I remove this, everything works as expected.
Now, I'm wondering if we can somehow "protect" our events from being intercepted like this as the component should really work in any case (that's why we chose this technology).
But I also would be very grateful for any hints to what might actually cause the problem.
Thanks a lot!!
n.prototype = window.Event.prototype,
window.CustomEvent = n
Looks like they overloaded CustomEvent and injected their own code.
This is the drawback of using 3rd party software.
In this case, only way to get around this is to get in early, and overload CustomEvent yourself.
But you then have the challenge of making their code work; because they did this overloading for a reason.
What is the 3rd party software? Publically shame them.
For those who want to try overloading, execute this early:
window.customeElements.define = () => {}
Related
I use a web based development environment for data entry forms. The environment lets me create rules that are triggered by form events. These events run in js in the browser but there is almost no support for debugging, which makes problem solving a nightmare.
The code in the browser has a central event handler, which has a logging feature but the quantity of information produced by it is so large, it makes finding what you need difficult. Think of info level logging gone mad. Plus you have to open a separate window to access the log.
I need to be able to log certain events to the console, or trigger breakpoints at specified rules. Is there a way to modify the environment's code below to allow it to call my debugger instead of (or in addition) to SFLog?
function handleEvent(n,t,q,r,u,f,e,o,s,h,c,l){
if(eventsCancelled!==!0){
SFLog({type:3,source:"handleEvent",category:"Events",
message:"{2} event fired from {1} - {0}",parameters:[n,t,q]});
var b="Events/Event[#SourceID='"+n+"'][#SourceType='"+t+"'][Name/text()="+q.xpathValueEncode()+"]";
//Rest of the event handler...
function SFLog(n){
if(checkExists(_debug)){var s=translateDebugLevel(n.type);
if(s>=_debug){
varu=n.type,e=n.source,r=n.category,q=n.message,h=n.parameters,o=checkExists(n.exception)? WriteExceptionXml(n.exception):null,t=n.data,l=checkExists(n.humanateData)?
n.humanateData:!0,f=(new Date).format("yyyy-MM-ddTHH:mm:ss:fff");
checkExists(t)&&(dataString=t.xml,checkExists(dataString)||(dataString=t),l===!0&&(dataString=Humanate(dataString)));
//more code for SFLog...
Cleaned Up Code
function handleEvent(n, t, q, r, u, f, e, o, s, h, c, l) {
if (eventsCancelled !== !0) {
SFLog({
type: 3,
source: "handleEvent",
category: "Events",
message: "{2} event fired from {1} - {0}",
parameters: [n, t, q]
});
var b = "Events/Event[#SourceID='" + n + "'][#SourceType='" + t + "'][Name/text()=" + q.xpathValueEncode() + "]";
//Rest of the event handler...
}
}
function SFLog(n) {
if (checkExists(_debug)) {
var s = translateDebugLevel(n.type);
if (s >= _debug)
{
varu = n.type;
e = n.source;
r = n.category;
q = n.message;
h = n.parameters;
o = checkExists(n.exception) ?
WriteExceptionXml(n.exception) :
null;
t = n.data;
l = checkExists(n.humanateData) ?
n.humanateData :
!0;
f = (new Date).format("yyyy-MM-ddTHH:mm:ss:fff");
checkExists(t) &&
(dataString = t.xml, checkExists(dataString) ||
(dataString = t), l === !0 && (dataString = Humanate(dataString)));
//more code for SFLog.
I agree with #Eddie but one solution could be to wrap the logger function and and override it, and only log the events you care about. e.g.:
function SFLog(n){
//old code
}
//run on the console, the first line, and then the second.
var oldLoggger = SFLog;
function SFLog(n) {
if(/*some criteria*/) {
oldLogger(n);
}
}
This way you can run the default logger with different conditions, but it probably would be best if you could modify the logger code itself to accept certain criteria, like, event type to log, or targetElement's ID, class etc.
PD: If you need to modify the eventHandler itself, you should:
remove the event handler first.
create your wrapper function.
add the wrapper function as event handler
I'd like to find a way to detect whether a observer has finished using a customized observable, which I created with Rx.Observable.create, such that the customized observable can end it and do some clean up properly.
So I created some test code as below to figure out what kind of fields are available on the observer object for this purpose.
var Rx = require("rx")
var source = Rx.Observable.create(function (observer) {
var i = 0;
setInterval(function(){
observer.onNext(i);
console.dir(observer);
i+=1
}, 1000)
});
var subscription = source.take(2).subscribe(
function (x) { console.log('onNext: %s', x); }
);
The output is as following
onNext: 0
{ isStopped: false,
observer:
{ isStopped: false,
_onNext: [Function],
_onError: [Function],
_onCompleted: [Function] },
m: { isDisposed: false, current: { dispose: [Function] } } }
onNext: 1
onCompleted
{ isStopped: true,
observer:
{ isStopped: false,
_onNext: [Function],
_onError: [Function],
_onCompleted: [Function] },
m: { isDisposed: true, current: null } }
It seems there are 3 fields on the observer object which seem to have something to do withmy goal, namely, observer.isStopped, observer.observer.isStopped and observer.m.isDiposed.
I was wondering what they all are about and which one I should choose.
==============================================================================
Motivations for my question
Based on Andre's suggestion, I add the scenario which motivated my question.
In my application, I was trying to do some UI animations based on the window.requestAnimationFrame(callback) mechanism. requestAnimationFrame will call the provided callback in a time determined by the browser render engine. The callback is supposed to do some animation step and recursively call requestAnimationFrame again until the end of animation.
I want to abstract this mechanism to an observable as below.
function animationFrameRenderingEventsObservable(){
return Rx.Observable.create(function(subscriber){
var fn = function(frameTimestmpInMs){
subscriber.onNext(frameTimestmpInMs);
window.requestAnimationFrame(fn)
};
window.requestAnimationFrameb(fn);
});
}
Then I can use it in various places where animation are needed. For one example, I need to draw some animation UNTIL the user touch the screen, I go
animationFrameRenderingEventsObservable()
.takeUntil(touchStartEventObservable)
.subscribe( animationFunc )
However, I need a way to stop the infinite recursion in animationFrameRenderingEventsObservable after the takeUntil(touchStartEventObservable) has ended the subscription.
Therefore, I modified animationFrameRenderingEventsObservable to
function animationFrameRenderingEventsObservable(){
return Rx.Observable.create(function(subscriber){
var fn = function(frameTimestmpInMs){
if (!subscriber.isStopped){
subscriber.onNext(frameTimestmpInMs);
window.requestAnimationFrame(fn)
}else{
subscriber.onCompleted();
}
};
window.requestAnimationFrameb(fn);
});
}
According to my test, the code works as expected. But, if, as Andre mentioned, use subscriber.isStopped or alike is not a correct way to so, then what is the correct way?
In the function you supply to create, you can return a cleanup function to call when the observer unsubscribes from your observable. You should supply a function which stops your animation frame requests. Here's a working observable that does what you want that I wrote a few years ago:
Rx.Observable.animationFrames = function () {
/// <summary>
/// Returns an observable that triggers on every animation frame (see https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame ).
/// The value that comes through the observable is the time(ms) since the previous frame (or the time since the subscribe call for the first frame)
/// </summary>
var request = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame,
cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame ||
window.msCancelAnimationFrame || window.msCancelRequestAnimationFrame;
return Rx.Observable.create(function (observer) {
var requestId,
startTime = window.mozAnimationStartTime || Date.now(),
callback = function (currentTime) {
// If we have not been disposed, then request the next frame
if (requestId !== undefined) {
requestId = request(callback);
}
observer.onNext(Math.max(0, currentTime - startTime));
startTime = currentTime;
};
requestId = request(callback);
return function () {
if (requestId !== undefined) {
var r = requestId;
requestId = undefined;
cancel(r);
}
};
});
};
Usage:
Rx.Observable.animationFrames().take(5).subscribe(function (msSinceLastFrame) { ... });
If you using observer.isStopped or related, you doing something wrong. These are not API functions, they are implementation details.
I'd like to find a way to detect whether a observer has finished using a customized observable, which I created with Rx.Observable.create, such that the customized observable can end it and do some clean up properly.
Observers do clean up when 'onCompleted' happens. In the Observable.create above, you should call observer.onCompleted() when you consider the custom observable to have ended, or never call observer.onCompleted() if the custom observable is meant to be infinite. Also, you should wrap the whole code inside Observable.create with try/catch and call observer.onError(err) in the catch.
If you are trying to make the Observable "clean up" when an observer "has finished using the observable", then you are doing it wrong. Essentially, if the custom observable needs to react to the observer, then it means the observer should also be an observable. Likely, Observable.create is not the tool for this.
Better tell what you are trying to accomplish instead of how to do something specific.
UPDATE:
Based on the animations you want to do: in the context of RxJS, requestAnimationFrame is a Scheduler, not an Observable. Use it from the RxJS-DOM library.
I am trying implement async event leveraging YUI3 library. So the application had been notified about event passed even with late subscription, simular like load or ready events do.
Here it is what I have so far, but no luck around.
YUI().use('event', 'event-custom', function(Y){
function onCustomEvent () {
Y.Global.on('custom:event', function(){
alert('custom fired');
});
}
window.setTimeout(onCustomEvent, 2000);
});
YUI().use('event', 'event-custom', function(Y){
Y.publish('custom:event', {
emitFacade: true,
broadcast: 2,
fireOnce: true,
async: true
});
function fireCustomEvent () {
Y.Global.fire('custom:event');
}
window.setTimeout(fireCustomEvent, 1000);
});
If anyone could give a hint what's wrong with this code? Thank you.
UPD:
After a bit investigations it turns out that async events work fine inside one use() instance and when not using Global broadcasting. So that's something either bug or limitation. Still discovering
Okay, at the high level the inconsistency with global events (how I understood it) lays in the sandbox nature of Y object. So at some point you could fire only sync events globally cause async parameters you subscribe to custom event made on Y instance and not passed further (and than YUI uses some defaults or whatever). This possibly makes sense but than why such kind of events should be fireable globally? Either I miss some substantial part of YUI and this is candidate for bug report.
Anyway I do not have time to dive deeper in YUI and what I really practically need could be wrapped in 40 lines of code:
YUI.add('async-pubsub', function(Y) {
var subscribers = {};
if ( !YUI.asyncPubSub ) {
YUI.namespace('asyncPubSub');
YUI.asyncPubSub = (function(){
var eventsFired = {};
function doPublishFor(name) {
var subscriber;
for ( subscriber in subscribers ) {
if ( subscriber === name ) {
(subscribers[name]).call();
delete ( subscribers[name] ); // Keep Planet clean
}
}
}
return {
'publish': function(name, options) {
eventsFired[name] = options || {};
doPublishFor(name);
},
'subscribe': function(name, callback) {
if ( subscribers[name] ) {
Y.log('More than one async subscriber per instance, overriding it.', 'warning', 'async-pubsub');
}
subscribers[name] = callback || function() {};
if ( eventsFired[name] ) {
window.setTimeout(
function () {
doPublishFor(name);
},0
);
}
}
};
})();
}
Y.asyncPubSub = YUI.asyncPubSub;
}, '1.0', {requires: []});
There is some limitation and room for optimization here, like ability subscribe only one action for one event per use instance, but I do not need more. I will also try to debug and enhance this snippet in future if there will be interest.
Still curious about YUI behavior, is it bug or something?
Hy there,
is it possible to control which records can be dragged and where they can be dropped (suppress drag-operation either right from the beginning or in the middle during hovering)?
What i need in detail is the following:
I'm having a grid with some groups (lets say male & female) and only want to activate the d&d inside group 'female' which means 2 things:
1.) I started dragging a record from group 'female' (Lisa). As soon as the drag is outside the group 'female' (above group 'male'...) it should display an error-state like when dragging outside the bounds of the grid:
2.) Starting to drag an item from group 'male' should either not be possible at all (just don't show the d&d panel) or show the error-state like mentioned above right from the beginning and never change to "correct"-state.
Thanks,
mike
After some digging around in the sources of ext i just found a solution which works but isn't perfect at all:
The "drop-allowed-indication" can be handled by the underlying DropZone which is created in onViewRender of the treeviewdragdrop-plugin. This is not documented but can be seen in the source-code of the plugin.
Everything that needs to be done (at least for this example) is to override/extend the onNodeOver- & onContainerOver-method of the DropZone to return the appropriate css-class for the drop-not-allowed- or drop-allowed-indication.
Ext.override(Ext.view.DropZone, {
onNodeOver: function(nodeData, source, e, data) {
if (data && data.records && data.records[0]) {
// The check should be better specified, e.g. a
// female with the name 'Malena' would be recognized as male!
if (nodeData.innerHTML.indexOf(data.records[0].get('sex')) < 0) {
return this.dropNotAllowed;
}
}
return this.callOverridden([nodeData, source, e, data]);
},
onContainerOver: function(source, e, data) {
return this.dropNotAllowed;
}
});
Working example: http://jsfiddle.net/suamikim/auXdQ/
There are a few things i don't like about this solution:
The override changes (per definition...) the behaviour of all DropZones in my application. How can i only override/extend the specific DropZone of one grid?I've tried the following:
Add an interceptor to the dropZone after the gridview has been rendered: http://jsfiddle.net/suamikim/uv8tX/
At first this seems to work because it shows the correct drop-allowed-indication but it drops the record even if the indicator shows that it's not allowed (it always shows the "green line"...)
Define a new dnd-plugin which extends the treeviewdragdrop-plugin and just override the onNodeOver-method of the dropZone after it's creation: http://jsfiddle.net/suamikim/5v67W/
This kind of does the opposite from the interception-method. It also shows the correct indication but it never shows the "green line" and won't allow the drop anywhere...
The class i'm overriding (Ext.view.DropZone) is marked private in the documentation with a note that it shouldn't be used directly...
I would really appreciate some comments on those 2 issues and maybe even some better solutions!
Thanks, mik
Edit:
I adjusted the version in which i defined a new dnd-plugin which extended the original gridviewdragdrop-plugin. The "magic" was to also extend gridviewdropzone and extend the onNodeOver-method instead of just overriding it.
This needs to be done because the original onNodeOver-method which is now called by callParent handles the "green line" and finally allows the drop.
The only thing my extended gridviewdragdrop-plugin does now is to create a instance of the new dropzone-class instead of the standard gridviewdropzone in the onViewRender-method.
This seems like a reasonable way so far:
// Extend the treeview dropzone
Ext.define('ExtendedGridViewDropZone', {
extend: 'Ext.grid.ViewDropZone',
onNodeOver: function(nodeData, source, e, data) {
if (data && data.records && data.records[0]) {
// The check should be specified, e.g. a female with the name 'Malena' would be recognized as male!
if (nodeData.innerHTML.indexOf(data.records[0].get('sex')) < 0) {
return this.dropNotAllowed;
}
}
return this.callParent(arguments);
},
onContainerOver: function(source, e, data) {
return this.dropNotAllowed;
}
});
Ext.define('ExtendedGridDnD', {
extend: 'Ext.grid.plugin.DragDrop',
alias: 'plugin.extendeddnd',
onViewRender: function(view) {
this.callParent(arguments);
// Create a instance of ExtendedGridViewDropZone instead of Ext.grid.ViewDropZone
this.dropZone = Ext.create('ExtendedGridViewDropZone', {
view: view,
ddGroup: this.dropGroup || this.ddGroup
});
}
});
Working example: http://jsfiddle.net/5v67W/1/
Nonetheless I'd still appreciate different approaches because it still feels like it could be done easier...
You can do it like this for Ext 5 and 6
On your treepanel definition:
listeners: {
viewready : 'onViewReady'
}
on your ViewController:
onViewReady : function (tree) {
var view = tree.getView(),
dd = view.findPlugin('treeviewdragdrop'),
rec;
dd.dropZone.onNodeOver = function (data, e) {
rec = view.getRecord(e.getTarget(view.itemSelector));
return rec.get('customProperty') === 'someValue' ? this.dropAllowed : this.dropNotAllowed;
}
},
reference https://www.sencha.com/forum/showthread.php?282685
https://www.sencha.com/blog/declarative-listeners-in-ext-js-5/
Suppose there are objects making subscriptions to a socket server like so:
socket.on('news', obj.socketEvent)
These objects have a short life span and are frequently created, generating many subscriptions. This seems like a memory leak and an error prone situation which would intuitively be prevented this way:
socket.off('news', obj.socketEvent)
before the object is deleted, but alas, there isn't an off method in the socket. Is there another method meant for this?
Edit: having found no answer I'm assigning a blank method to overwrite the wrapper method for the original event handler, an example follows.
var _blank = function(){};
var cbProxy = function(){
obj.socketEvent.apply(obj, arguments)
};
var cbProxyProxy = function(){
cbProxy.apply ({}, arguments)
}
socket.on('news', cbProxyProxy);
// ...and to unsubscribe
cbProxy = _blank;
From looking at the source of socket.io.js (couldn't find it in documentation anywhere), I found these two functions:
removeListener = function(name, fn)
removeAllListeners = function(name)
I used removeAllListeners successfully in my app; you should be able to choose from these:
socket.removeListener("news", cbProxy);
socket.removeAllListeners("news");
Also, I don't think your solution of cbProxy = _blank would actually work; that would only affect the cbProxy variable, not any actual socket.io event.
If you want to create listeners that "listens" only once use socket.once('news',func). Socket.io automatically will distroy the listener after the event happened - it's called "volatile listener".
Looking at the code of current version of Socket.io Client (1.4.8) it seems that off, removeAllListeners, removeEventListener are all pointing to the same function.
Calling any of those, providing event name and/or callback, gives the desired result. Not providing anything at all seems to reset everything.
Please do be cautious about the fn/callback argument. It has to be the same instance used in the code.
Example:
var eventCallback = function(data) {
// do something nice
};
socket.off('eventName', eventCallback);
Would work as expected.
Example (will also work):
function eventCallback(data) {
// do something nice
}
socket.off('eventName', eventCallback);
Please be cautious that the callback you are trying to remove is the one that you passed in (this one can bring a lot of confusion and frustration).
This example implements a wrapper around initial callback, trying to remove that would not work as the real callback being added is an undisclosed closure instance: http://www.html5rocks.com/en/tutorials/frameworks/angular-websockets/
Here is the link to that specific line in the codebase: https://github.com/socketio/socket.io-client/blob/master/socket.io.js#L1597
Socket.io version 0.9.16 implements removeListener but not off.
You can use removeListener instead of off when unsubscribing, or simply implement off as follows:
var socket = io.connect(url);
socket.off = socket.removeListener;
If you are using the Backbone listenTo event subscription approach, you'll need to implement the above as Backbone calls off when unsubscribing events.
I found that in socket.io 0.9.11 and Chrome24 socket.io removeListener doesn't work.
this modified version works for me:
EventEmitter.prototype.removeListener = function (name, fn) {
if (this.$events && this.$events[name]) {
var list = this.$events[name];
if (io.util.isArray(list)) {
var pos = -1;
for (var i = 0, l = list.length; i < l; i++) {
if (list[i].toString() === fn.toString() || (list[i].listener && list[i].listener === fn)) {
pos = i;
break;
}
}
if (pos < 0) {
return this;
}
list.splice(pos, 1);
if (!list.length) {
delete this.$events[name];
}
} else {
if (list.toString() === fn.toString() || (list.listener && list.listener === fn)) {
delete this.$events[name];
}
}
}
return this;
};
Since I had a spot of troubles making this work figured I'd chime in here as well, along with a nice updated answer for 2017. Thanks to #Pjotr for pointing out that it has to be the same callback instance.
Example with Angular2 TypeScript in a socket-io.subscriber service. Note the "newCallback" wrapper
private subscriptions: Array<{
key: string,
callback: Function
}>;
constructor() {
this.subscriptions = [];
}
subscribe(key: string, callback: Function) {
let newCallback = (response) => callback(response);
this.socket.on(key, newCallback);
return this.subscriptions.push({key: key, callback: newCallback}) - 1;
}
unsubscribe(i: number) {
this.socket.removeListener(this.subscriptions[i].key, this.subscriptions[i].callback);
}
Removing an event listener on the client
var Socket = io.connect();
Socket.removeListener('test', test);
Also on java client, it can be done the same way with the Javascript client. I've pasted from socket.io.
// remove all listeners of the connect event
socket.off(Socket.EVENT_CONNECT);
listener = new Emitter.Listener() { ... };
socket.on(Socket.EVENT_CONNECT, listener);
// remove the specified listener
socket.off(Socket.EVENT_CONNECT, listener);
Pre-store the events using an array, and by the time you need to unsubscribe them, use the off method, which is a built in method from socket.io:
// init
var events = []
// store
events.push("eventName")
// subscribe
socket.on("eventName", cb)
// remove
events = events.filter(event => event!="eventName")
// unsubscribe
socket.off("eventName")
To add to #Andrew Magee, here is an example of unsubscribing socket.io events in Angular JS, and of course works with Vanilla JS:
function handleCarStarted ( data ) { // Do stuff }
function handleCarStopped ( data ) { // Do stuff }
Listen for events:
var io = $window.io(); // Probably put this in a factory, not controller instantiation
io.on('car.started', handleCarStarted);
io.on('car.stopped', handleCarStopped);
$scope.$on('$destroy', function () {
io.removeListener('car.started', handleCarStarted);
io.removeListener('car.stopped', handleCarStopped);
});
This has helped me in both Angular 8 and React 16.8:
receiveMessage() {
let newCallback = (data) => {
this.eventEmitter.emit('add-message-response', data);
};
this.socket.on('add-message-response', newCallback);
this.subscriptions.push({key: 'add-message-response', callback: newCallback});
}
receiveMessageRemoveSocketListener() {
this.findAndRemoveSocketEventListener('add-message-response');
}
findAndRemoveSocketEventListener (eventKey) {
let foundListener = this.subscriptions.find( (subscription) => subscription.key === eventKey );
if(!foundListener) {
return;
}
this.socket.removeListener(foundListener.key, foundListener.callback);
this.subscriptions = this.subscriptions.filter( (subscription) => subscription.key !== eventKey );
}
Reason for using an Array of Subscriptions is that when you Subscribe to an event multiple times and you don't remove an unsubscribed subscription from the Subscription list you will most probably be right at first time you remove the subscription from the list, but later subscriptions will not be removed as you will be finding first instance only every time you unsubscribe the event.
You can simply call receiveMessage(); to subscribe to an the event and receiveMessageRemoveSocketListener(); to Unsubscribe.