I have the following simple NodeJS script and want to modify it slightly....
var sys = require( 'sys' ), net = require( 'net' );
var outputserver = net.createServer( function( stream ) {
stream.addListener( 'data', function( data ) {
sys.puts( data );
//Want to output anything from the clientserver data here
});
}).listen( 7001, 'localhost' );
var clientserver = net.createServer( function( stream ) {
stream.addListener( 'data', function( data ) {
sys.puts( data );
});
}).listen( 7000, 'localhost' );
I need anything coming in from the "clientserver" to be output to the "outputserver" stream. There will be 50-60 clients connecting to the the "clientserver"
This should work:
var util = require('util'), net = require('net');
var outServer = net.createServer(function(outStream) {
outStream.on('data', function(data) {
util.puts(data);
});
var inServer = net.createServer(function(inStream) {
inStream.pipe(outStream, {end: false});
});
inServer.listen(7001, 'localhost');
});
outServer.listen(7000, 'localhost');
Related
I found very useful article on the web
for contact form 7
<?php
function ajax_cf7_populate_values() {
// read the CSV file in the $makes_models_years array
$makes_models_years = array();
$uploads_folder = wp_upload_dir()['basedir'];
$file = fopen($uploads_folder.'\make_model_year.csv', 'r');
$firstline = true;
while (($line = fgetcsv($file)) !== FALSE) {
if ($firstline) {
$firstline = false;
continue;
}
$makes_models_years[$line[0]][$line[1]][] = $line[2];
}
fclose($file);
// setup the initial array that will be returned to the the client side script as a JSON object.
$return_array = array(
'makes' => array_keys($makes_models_years),
'models' => array(),
'years' => array(),
'current_make' => false,
'current_model' => false
);
// collect the posted values from the submitted form
$make = key_exists('make', $_POST) ? $_POST['make'] : false;
$model = key_exists('model', $_POST) ? $_POST['model'] : false;
$year = key_exists('year', $_POST) ? $_POST['year'] : false;
// populate the $return_array with the necessary values
if ($make) {
$return_array['current_make'] = $make;
$return_array['models'] = array_keys($makes_models_years[$make]);
if ($model) {
$return_array['current_model'] = $model;
$return_array['years'] = $makes_models_years[$make][$model];
if ($year) {
$return_array['current_year'] = $year;
}
}
}
// encode the $return_array as a JSON object and echo it
echo json_encode($return_array);
wp_die();
}
// These action hooks are needed to tell WordPress that the cf7_populate_values() function needs to be called
// if a script is POSTing the action : 'cf7_populate_values'
add_action( 'wp_ajax_cf7_populate_values', 'ajax_cf7_populate_values' );
add_action( 'wp_ajax_nopriv_cf7_populate_values', 'ajax_cf7_populate_values' );
and some java
<script>
(function($) {
// create references to the 3 dropdown fields for later use.
var $makes_dd = $('[name="makes"]');
var $models_dd = $('[name="models"]');
var $years_dd = $('[name="years"]');
// run the populate_fields function, and additionally run it every time a value changes
populate_fields();
$('select').change(function() {
populate_fields();
});
function populate_fields() {
var data = {
// action needs to match the action hook part after wp_ajax_nopriv_ and wp_ajax_ in the server side script.
'action' : 'cf7_populate_values',
// pass all the currently selected values to the server side script.
'make' : $makes_dd.val(),
'model' : $models_dd.val(),
'year' : $years_dd.val()
};
// call the server side script, and on completion, update all dropdown lists with the received values.
$.post('/wp-admin/admin-ajax.php', data, function(response) {
all_values = response;
$makes_dd.html('').append($('<option>').text(' -- choose make -- '));
$models_dd.html('').append($('<option>').text(' -- choose model -- '));
$years_dd.html('').append($('<option>').text(' -- choose year -- '));
$.each(all_values.makes, function() {
$option = $("<option>").text(this).val(this);
if (all_values.current_make == this) {
$option.attr('selected','selected');
}
$makes_dd.append($option);
});
$.each(all_values.models, function() {
$option = $("<option>").text(this).val(this);
if (all_values.current_model == this) {
$option.attr('selected','selected');
}
$models_dd.append($option);
});
$.each(all_values.years, function() {
$option = $("<option>").text(this).val(this);
if (all_values.current_year == this) {
$option.attr('selected','selected');
}
$years_dd.append($option);
});
},'json');
}
})( jQuery );
</script>
but when i add it to me website nothing appear in the dropdowns. They are empty.
I tried to contact the blogger but there is no answer yet. Give me some advice
I copied the csv almost as the one in the post. So I think the function is mistaken... somewhere
I found the solution: in the article the file name is mistaken. It has to be "make_model_year.csv" !!!
Hi I'm using Word press visual composer .. the problem is that with some pages(not all pages) , the front editor is not working , it just keep loading endlessly ,at first it wasn't working with all pages .. but when I added a blank page , Front editor worked with the blank page and some other pages , so what to do to make visual composer front editor works with these pages?
I'm using word press the 7 theme.
this is my suffering:
There may be many reasons for this but the root is js error.
1. at first disable page "preloader" and try.
2. If not working try disabling other plugins for wordpress which may have js conflict.
3. The best way: Have a look on console log for js error in browser's developer tools and fix them.
i had problem with visual. In my case helped when i changed on classic mode and return to backend editor.
This issue is mostly related to composer-view.js, I faced the same issue and it got resolved after following this link -
visual-composer-templateget-is-not-a-functi and Visual Composer is not working
You need to replace old code of composer-view.js as follow. (ps:- backup your old file before replacing this code.)
You can find this file at following location-
wp-content/plugins/js_composer/assets/js/backend
Old Code
html2element: function ( html ) {
var attributes = {},
$template;
if ( _.isString( html ) ) {
this.template = _.template( html );
$template = $( this.template( this.model.toJSON(), vc.templateOptions.default ).trim() );
} else {
this.template = html;
$template = html;
}
_.each( $template.get( 0 ).attributes, function ( attr ) {
attributes[ attr.name ] = attr.value;
} );
this.$el.attr( attributes ).html( $template.html() );
this.setContent();
this.renderContent();
}
Replace with new one as follows-
html2element:function (html) {
var attributes = {},
$template;
if (_.isString(html)) {
this.template = _.template(html);
} else {
try {
this.template = _.template(html());
} catch (err) {
this.template = html;
}
}
$template = $(this.template(this.model.toJSON()).trim());
_.each($template.get(0).attributes, function (attr) {
attributes[attr.name] = attr.value;
});
this.$el.attr(attributes).html($template.html());
this.setContent();
this.renderContent();
}
then also replace the Render Function
Old code
render: function () {
var $shortcode_template_el = $( '#vc_shortcode-template-' + this.model.get( 'shortcode' ) );
if ( $shortcode_template_el.is( 'script' ) ) {
this.html2element( _.template( $shortcode_template_el.html(),
this.model.toJSON(),
vc.templateOptions.default ) );
} else {
var params = this.model.get( 'params' );
$.ajax( {
type: 'POST',
url: window.ajaxurl,
data: {
action: 'wpb_get_element_backend_html',
data_element: this.model.get( 'shortcode' ),
data_width: _.isUndefined( params.width ) ? '1/1' : params.width,
_vcnonce: window.vcAdminNonce
},
dataType: 'html',
context: this
} ).done( function ( html ) {
this.html2element( html );
} );
}
this.model.view = this;
this.$controls_buttons = this.$el.find( '.vc_controls > :first' );
return this;
}
Replace with new code as follows-
render: function () {
var $shortcode_template_el = $( '#vc_shortcode-template-' + this.model.get( 'shortcode' ) );
if ( $shortcode_template_el.is( 'script' ) ) {
var newHtmlCode = _.template( $shortcode_template_el.html(),
this.model.toJSON(),
vc.templateOptions.default );
if(!_.isString(newHtmlCode)){
newHtmlCode = $shortcode_template_el.html();
}
this.html2element( newHtmlCode );
} else {
var params = this.model.get( 'params' );
$.ajax( {
type: 'POST',
url: window.ajaxurl,
data: {
action: 'wpb_get_element_backend_html',
data_element: this.model.get( 'shortcode' ),
data_width: _.isUndefined( params.width ) ? '1/1' : params.width,
_vcnonce: window.vcAdminNonce
},
dataType: 'html',
context: this
} ).done( function ( html ) {
this.html2element( html );
} );
}
this.model.view = this;
this.$controls_buttons = this.$el.find( '.vc_controls > :first' );
return this;
}
I want to improve the process of uploading pictures in a Real Estate Website. This website is running WordPress 3.8. The theme offers front end submission with a very simple interface. The user selects the images (one by one) and then clicks to add. Finally when the user submit the listing all the images are uploaded at once. This is the screenshot of how it looks: Original Option: Listing Images.
This is the JQuery Plugin I am currently using,
/*!
* jQuery imagesLoaded plugin v2.1.1
* http://github.com/desandro/imagesloaded
*
* MIT License. by Paul Irish et al.
*/
/*jshint curly: true, eqeqeq: true, noempty: true, strict: true, undef: true, browser: true */
/*global jQuery: false */
;(function($, undefined) {
'use strict';
// blank image data-uri bypasses webkit log warning (thx doug jones)
var BLANK = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
$.fn.imagesLoaded = function( callback ) {
var $this = this,
deferred = $.isFunction($.Deferred) ? $.Deferred() : 0,
hasNotify = $.isFunction(deferred.notify),
$images = $this.find('img').add( $this.filter('img') ),
loaded = [],
proper = [],
broken = [];
// Register deferred callbacks
if ($.isPlainObject(callback)) {
$.each(callback, function (key, value) {
if (key === 'callback') {
callback = value;
} else if (deferred) {
deferred[key](value);
}
});
}
function doneLoading() {
var $proper = $(proper),
$broken = $(broken);
if ( deferred ) {
if ( broken.length ) {
deferred.reject( $images, $proper, $broken );
} else {
deferred.resolve( $images );
}
}
if ( $.isFunction( callback ) ) {
callback.call( $this, $images, $proper, $broken );
}
}
function imgLoadedHandler( event ) {
imgLoaded( event.target, event.type === 'error' );
}
function imgLoaded( img, isBroken ) {
// don't proceed if BLANK image, or image is already loaded
if ( img.src === BLANK || $.inArray( img, loaded ) !== -1 ) {
return;
}
// store element in loaded images array
loaded.push( img );
// keep track of broken and properly loaded images
if ( isBroken ) {
broken.push( img );
} else {
proper.push( img );
}
// cache image and its state for future calls
$.data( img, 'imagesLoaded', { isBroken: isBroken, src: img.src } );
// trigger deferred progress method if present
if ( hasNotify ) {
deferred.notifyWith( $(img), [ isBroken, $images, $(proper), $(broken) ] );
}
// call doneLoading and clean listeners if all images are loaded
if ( $images.length === loaded.length ) {
setTimeout( doneLoading );
$images.unbind( '.imagesLoaded', imgLoadedHandler );
}
}
// if no images, trigger immediately
if ( !$images.length ) {
doneLoading();
} else {
$images.bind( 'load.imagesLoaded error.imagesLoaded', imgLoadedHandler )
.each( function( i, el ) {
var src = el.src;
// find out if this image has been already checked for status
// if it was, and src has not changed, call imgLoaded on it
var cached = $.data( el, 'imagesLoaded' );
if ( cached && cached.src === src ) {
imgLoaded( el, cached.isBroken );
return;
}
// if complete is true and browser supports natural sizes, try
// to check for image status manually
if ( el.complete && el.naturalWidth !== undefined ) {
imgLoaded( el, el.naturalWidth === 0 || el.naturalHeight === 0 );
return;
}
// cached images don't fire load sometimes, so we reset src, but only when
// dealing with IE, or image is complete (loaded) and failed manual check
// webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
if ( el.readyState || el.complete ) {
el.src = BLANK;
el.src = src;
}
});
}
return deferred ? deferred.promise( $this ) : $this;
};
})(jQuery);
My goal is to have a more flexible system, where all the images can be selected at the same time and it starts loading right away. This will speed up the process and improve user experience. Also to arrange them in any order by moving them around. This is an example I found on another website. See screenshot: New Option: Multiple Image Upload
What programing language is good for this development? Any recommendations of where I can find code snippets for this application? Thanks in advance for your help!!
rough draft.....you need jquery and wordpress media js..just watch the js variable names below if there are errors it will be with these...
php in functions file:
if(function_exists( 'wp_enqueue_media' )){
wp_enqueue_media();
}
javascript...add to the page header..wp_enqueue_scripts or to your template (do this first to make sure its working!) you'll need your element called upload_image_button or change accordinely
// Uploading files
var media_uploader;
jQuery('.upload_image_button').live('click', function( event ){
var button = jQuery( this );
// If the media uploader already exists, reopen it.
if ( media_uploader ) {
media_uploader.open();
return;
}
// Create the media uploader.
media_uploader = wp.media.frames.media_uploader = wp.media({
title: button.data( 'uploader-title' ),
// Tell the modal to show only images.
library: {
type: 'image',
query: false
},
button: {
text: button.data( 'uploader-button-text' ),
},
multiple: button.data( 'uploader-allow-multiple' )
});
// Create a callback when the uploader is called
media_uploader.on( 'select', function() {
var selection = media_uploader.state().get('selection'),
input_name = button.data( 'input-name' ),
bucket = $( '#' + input_name + '-thumbnails');
selection.map( function( attachment ) {
attachment = attachment.toJSON();
// console.log(attachment);
bucket.append(function() {
return '<img src="'+attachment.sizes.thumbnail.url+'" width="'+attachment.sizes.thumbnail.width+'" height="'+attachment.sizes.thumbnail.height+'" class="submission_thumb thumbnail" /><input name="'+input_name+'[]" type="hidden" value="'+attachment.id+'" />'
});
});
});
// Open the uploader
media_uploader.open();
});
template file:
<span class="upload_image_button alt_button" data-input-name="images" data-uploader- title="Upload Images" data-uploader-button-text="Add to Submission" data-uploader-allow-multiple="true">Upload</span>
php $_POST return
if ( !empty( $_POST['submission_images'] ) ) {
// do something with the files, set featured img, add to content or save post_meta
}
or..............i came across a plugin that does this a lot better........sorry its in OOP and designed on back end but you can modify for front end! The problem with multi file uploader from WP is it required users to hit "CTRL" + click with no guidance....massive problem on front-end forms...this one you can add more guidance to easily...sorry i havent a frontend sample yet, i have yet to create :)
"Multi File Upload"
e.g.
public function render_meta_box_content($post)
{
// Add an nonce field so we can check for it later.
wp_nonce_field('miu_inner_custom_box', 'miu_inner_custom_box_nonce');
// Use get_post_meta to retrieve an existing value from the database.
$value = get_post_meta($post->ID, '_ad_images', true);
$metabox_content = '<div id="miu_images"></div><input type="button" onClick="addRow()" value="Add Image" class="button" />';
echo $metabox_content;
$images = unserialize($value);
$script = "<script>
itemsCount= 0;";
if (!empty($images))
{
foreach ($images as $image)
{
$script.="addRow('{$image}');";
}
}
$script .="</script>";
echo $script;
}
save function
public function save_image($post_id)
{
/*
* We need to verify this came from the our screen and with proper authorization,
* because save_post can be triggered at other times.
*/
// Check if our nonce is set.
if (!isset($_POST['miu_inner_custom_box_nonce']))
return $post_id;
$nonce = $_POST['miu_inner_custom_box_nonce'];
// Verify that the nonce is valid.
if (!wp_verify_nonce($nonce, 'miu_inner_custom_box'))
return $post_id;
// If this is an autosave, our form has not been submitted,
// so we don't want to do anything.
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return $post_id;
// Check the user's permissions.
if ('page' == $_POST['post_type'])
{
if (!current_user_can('edit_page', $post_id))
return $post_id;
} else
{
if (!current_user_can('edit_post', $post_id))
return $post_id;
}
/* OK, its safe for us to save the data now. */
// Validate user input.
$posted_images = $_POST['miu_images'];
$miu_images = array();
foreach ($posted_images as $image_url)
{
if(!empty ($image_url))
$miu_images[] = esc_url_raw($image_url);
}
// Update the miu_images meta field.
update_post_meta($post_id, '_ad_images', serialize($miu_images));
}
js file
jQuery(document).ready(function(){
jQuery('.miu-remove').live( "click", function(e) {
e.preventDefault();
var id = jQuery(this).attr("id")
var btn = id.split("-");
var img_id = btn[1];
jQuery("#row-"+img_id ).remove();
});
var formfield;
var img_id;
jQuery('.Image_button').live( "click", function(e) {
e.preventDefault();
var id = jQuery(this).attr("id")
var btn = id.split("-");
img_id = btn[1];
jQuery('html').addClass('Image');
formfield = jQuery('#img-'+img_id).attr('name');
tb_show('', 'media-upload.php?type=image&TB_iframe=true');
return false;
});
window.original_send_to_editor = window.send_to_editor;
window.send_to_editor = function(html){
if (formfield) {
fileurl = jQuery('img',html).attr('src');
jQuery('#img-'+img_id).val(fileurl);
tb_remove();
jQuery('html').removeClass('Image');
} else {
window.original_send_to_editor(html);
}
};
});
function addRow(image_url){
if(typeof(image_url)==='undefined') image_url = "";
itemsCount+=1;
var emptyRowTemplate = '<div id=row-'+itemsCount+'> <input style=\'width:70%\' id=img- '+itemsCount+' type=\'text\' name=\'miu_images['+itemsCount+']\' value=\''+image_url+'\' />'
+'<input type=\'button\' href=\'#\' class=\'Image_button button\' id=\'Image_button- '+itemsCount+'\' value=\'Upload\'>'
+'<input class="miu-remove button" type=\'button\' value=\'Remove\' id=\'remove-'+itemsCount+'\' /></div>';
jQuery('#miu_images').append(emptyRowTemplate);
}
I am trying to use an Asterisk Manager NPM module in Meteor, but am having difficulties with processing emitted events.
This NPM module establishes a permanent connection to Asterisk Manager and emits whatever Events it receives from Asterisk. I've managed to patch the code so that it runs in Meteor. It connects to Asterisk, emits events and I can log them to console, but once I try to do something with the data, like insert it into a collection, I receive the following error:
Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.
How do I overcome that? Thank you.
server side code:
var ami = new AsteriskManager( { username: 'meteor', password: '123456' } );
ami.on('ami_data', function(data){
console.log(data); // <- this works fine
// the following causes the error
EventsLog.insert({ timestamp: (new Date()).getTime(),
data: data});
});
ami.connect(function(){});//creates a socket connection and sends the login action
the patched npm module code:
var util = Npm.require('util');
var events = Npm.require('events').EventEmitter;
var net = Npm.require('net');
var AsteriskConstructor = function AsteriskManager(params){
params = params || {};
this.net = net;
this.CRLF = "\r\n";
this.END = "\r\n\r\n";
this.buffer = "";
this.port = params.port || 5038;
this.host = params.host || 'localhost';
this.username = params.username || 'username';
this.password = params.password || 'password';
this.enable_debug = params.debug || false;
this.reconnect = params.reconnect || false;
this.reconnect_after = params.reconnect_after || 3000;
this.events = (params.events != undefined ? params.events : true);
this.identifier = params.identifier || false;
this.ami_encoding = params.ami_encoding || 'ascii';
};
AsteriskManager = AsteriskConstructor;
util.inherits(AsteriskManager, events);
AsteriskManager.prototype.connect = function(connect_cb, data_cb){
var self = this;
self.debug('running ami connect');
self.socket = null;
self.socket = this.net.createConnection(this.port, this.host);//reopen it
self.socket.setEncoding(this.ami_encoding);
self.socket.setKeepAlive(true, 500);
self.socket.on('connect', function(){
self.debug('connected to Asterisk AMI');
//login to the manager interface
self.send({Action: 'login', Username : self.username, Secret : self.password, Events: (self.events ? 'on' : 'off')});
if(connect_cb && typeof connect_cb == 'function'){
connect_cb();
}
}).on('data', function(data){
if(data_cb && typeof data_cb == 'function'){
data_cb(data);
}
var all_events = self.processData(data);
for(var i in all_events){
var result = all_events[i];
if(result.response && result.message && /Authentication/gi.exec(result.message) == 'Authentication'){
self.emit('ami_login', ((result.response == 'Success') ? true : false) ,result);
}
self.emit('ami_data', result);
}
}).on('drain', function(){
self.debug('Asterisk Socket connection drained');
self.emit('ami_socket_drain');
}).on('error', function(error){
if(error){
self.debug('Asterisk Socket connection error, error was: ' + error);//prob lost connection to ami due to asterisk restarting so restart the connection
}
self.emit('ami_socket_error', error);
}).on('timeout',function(){
self.debug('Asterisk Socket connection has timed out');
self.emit('ami_socket_timeout');
}).on('end', function() {
self.debug('Asterisk Socket connection ran end event');
self.emit('ami_socket_end');
}).on('close', function(had_error){
self.debug('Asterisk Socket connection closed, error status - ' + had_error);
self.emit('ami_socket_close', had_error);
if(self.reconnect){
self.debug('Reconnecting to AMI in ' + self.reconnect_after);
setTimeout(function() {
self.connect(connect_cb, data_cb);
}, self.reconnect_after);
}
});
}
AsteriskManager.prototype.disconnect = function(){
this.reconnect = false;//just in case we wanted it to reconnect before, we've asked for it to be closed this time so make sure it doesnt reconnect
this.socket.end(this.generateSocketData({Action: 'Logoff'}));
}
AsteriskManager.prototype.destroy = function(){
this.socket.destroy();
}
AsteriskManager.prototype.processData = function(data, cb){
/*
Thanks to mscdex for this bit of code that takes many lots of data and sorts them out into one if needed!
https://github.com/mscdex/node-asterisk/blob/master/asterisk.js
*/
data = data.toString();
if (data.substr(0, 21) == "Asterisk Call Manager"){
data = data.substr(data.indexOf(this.CRLF)+2); // skip the server greeting when first connecting
}
this.buffer += data;
var iDelim, info, headers, kv, type, all_events = [];
while ((iDelim = this.buffer.indexOf(this.END)) > -1) {
info = this.buffer.substring(0, iDelim+2).split(this.CRLF);
this.buffer = this.buffer.substr(iDelim + 4);
result = {}; type = ""; kv = [];
for (var i=0,len=info.length; i<len; i++) {
if (info[i].indexOf(": ") == -1){
continue;
}
kv = info[i].split(": ", 2);
kv[0] = kv[0].toLowerCase().replace("-", "");
if (i==0){
type = kv[0];
}
result[kv[0]] = kv[1];
}
if(this.identifier){
result.identifier = this.identifier;
}
all_events.push(result);
}
return all_events;
}
AsteriskManager.prototype.debug = function(data){
if(this.enable_debug){
console.log(data);
}
}
AsteriskManager.prototype.generateRandom = function(){
return Math.floor(Math.random()*100000000000000000);
}
AsteriskManager.prototype.generateSocketData = function(obj){
var str = '';
for(var i in obj){
str += (i + ': ' + obj[i] + this.CRLF);
}
return str + this.CRLF;
}
AsteriskManager.prototype.send = function(obj, cb) {
//check state of connection here, if not up then bail out
if(!obj.ActionID){
obj.ActionID = this.generateRandom();
}
//maybe i should be checking if this socket is writeable
if(this.socket != null && this.socket.writable){
this.debug(obj);
this.socket.write(this.generateSocketData(obj), this.ami_encoding, cb);
}else{
this.debug('cannot write to Asterisk Socket');
this.emit('ami_socket_unwritable');
}
}
As the error message says "Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment"
ami.on('ami_data', Meteor.bindEnvironment( function(data){
console.log(data); // <- this works fine
// the following causes the error
EventsLog.insert({ timestamp: (new Date()).getTime(),
data: data});
}, function( error) { console.log( error);})
);
There are a lot of other examples around.
If the server code above is not in a Fiber you might get "Meteor code must always run within a Fiber" error.
How I pause a Server Sent Event connection? Is it even possible, or do I have to close the SSE and then reopen it and assign all of the event handlers again?
For example I would like to do (this is all theoretical, I do not know the pause/restart function names):
var source = new EventSource(url);
source.addEventListener("something", somefunction, false);
source.addEventListener("somethingElse", somefunction2, false);
//...some code
source.pause();
//...some code
source.restart();
Yes, that's what technically needs to happen but you can abstract it away. Note: This one only connects after you do .connect()
function EventSource2(url) {
this.url = url;
this.es = null;
this.listeners = {};
}
EventSource2.prototype = {
constructor: EventSource2,
connect: function() {
this.es = new EventSource(this.url);
this.bindEvents();
},
disconnect: function() {
this.es.close();
this.es = null;
},
bindEvents: function() {
for ( var type in this.listeners ) {
var evs = this.listeners[type];
for( var i = 0; i < evs.length; ++i ) {
this.es.addEventListener( type, evs[i], false );
}
}
},
addEventListener: function( type, fn ) {
if( !this.listeners[type] ) {
this.listeners[type] = [];
}
this.listeners[type].push( fn );
if( this.es ) {
this.bindEvents();
}
}
}
Usage:
var source = new EventSource2(url);
source.addEventListener("something", somefunction, false);
source.addEventListener("somethingElse", somefunction2, false);
source.connect();
source.disconnect();
source.connect();