Coder Social home page Coder Social logo

miguelgrinberg / python-socketio Goto Github PK

View Code? Open in Web Editor NEW
3.8K 59.0 566.0 1.52 MB

Python Socket.IO server and client

License: MIT License

Python 99.97% Shell 0.03%
socket-io socketio socketio-server websocket long-polling low-latency web-server python asyncio eventlet

python-socketio's Introduction

python-socketio

Build status codecov

Python implementation of the Socket.IO realtime client and server.

Sponsors

The following organizations are funding this project:

Socket.IO
Socket.IO
Add your company here!

Many individual sponsors also support this project through small ongoing contributions. Why not join them?

Version compatibility

The Socket.IO protocol has been through a number of revisions, and some of these introduced backward incompatible changes, which means that the client and the server must use compatible versions for everything to work.

If you are using the Python client and server, the easiest way to ensure compatibility is to use the same version of this package for the client and the server. If you are using this package with a different client or server, then you must ensure the versions are compatible.

The version compatibility chart below maps versions of this package to versions of the JavaScript reference implementation and the versions of the Socket.IO and Engine.IO protocols.

JavaScript Socket.IO version Socket.IO protocol revision Engine.IO protocol revision python-socketio version
0.9.x 1, 2 1, 2 Not supported
1.x and 2.x 3, 4 3 4.x
3.x and 4.x 5 4 5.x

Resources

python-socketio's People

Contributors

aaqibb13 avatar almogcohen avatar andreipashkin avatar andreyrusanov avatar chrisdoehring avatar cromfel avatar dbanty avatar dbrnz avatar dependabot[bot] avatar dimastbk avatar eserzomcity avatar etseidler avatar ezio-melotti avatar flocko-motion avatar fover23 avatar githk avatar greyli avatar hugovk avatar kurlov avatar lazylactus avatar mekicha avatar miguelgrinberg avatar molkree avatar musicinmybrain avatar sillygod avatar spezifanta avatar tsangwpx avatar uberi avatar vincentm avatar xarg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-socketio's Issues

How to make your sample server run on HTTPS?

Hi can you explain how to make your sample code run on HTTPS?

import socketio
import eventlet
import eventlet.wsgi
from flask import Flask, render_template

sio = socketio.Server()
app = Flask(__name__)

@app.route('/')
def index():
    """Serve the client-side application."""
    return render_template('index.html')

@sio.on('connect', namespace='/chat')
def connect(sid, environ):
    print("connect ", sid)

@sio.on('chat message', namespace='/chat')
def message(sid, data):
    print("message ", data)
    sio.emit('reply', room=sid)

@sio.on('disconnect', namespace='/chat')
def disconnect(sid):
    print('disconnect ', sid)

if __name__ == '__main__':
    # wrap Flask application with engineio's middleware
    app = socketio.Middleware(sio, app)

    # deploy as an eventlet WSGI server
    eventlet.wsgi.server(eventlet.listen(('', 8000)), app)

Cannot connect to server from javascript

When connecting to my server from a html/javascipt file I get the following error:

GET https://127.0.0.1:8000/socket.io/socket.io.js net::ERR_CONNECTION_REFUSED
Uncaught ReferenceError: io is not defined

This is how I connect in the HTML file:

<script src="https://1270.0.0.1:8000/socket.io/socket.io.js"></script>

And this is how I connect in the JS file:

var socket = io('https://127.0.0.1:8000/', {secure: true});

I am emitting values from the server. This works when I do it with NodeJS but I wanted it to be a python server, any help appreciated!

Websockets handshake error

If I force socket.io into websockets mode

var socket = io.connect('//' + document.domain + ':' + location.port + namespace, {
    'transports': ['websocket']
});

I always end up with an error

WebSocket connection to 'ws://localhost:7200/socket.io/?EIO=3&transport=websocket' failed: Error during WebSocket handshake: Unexpected response code: 200

I am using http://cdn.socket.io/socket.io-1.3.6.js

Is there something I am missing. I tried setting the url to ws://, but it didn't change anything. Polling mode works fine.

Virtual host based requests

Hey,

Thanks a bunch for building a more up to date SocketIO implementation... Been a massive help!

Anyway, I'm trying to implement a virtual-host based approach to socketIO server. There's a whole bunch of reasons for this, but the main one is that the project I'm working on would benefit from being a kind of SaaS style, where one-codebase handles all.

Ideally I want to avoid spinning up multiple codebase instances per account instance.

e.g. unicorns.hostname.com and magic.example.com both run from the same code instance and server infrastructure on the front-end but the back-end will separate my data domains separately based on the hostname they're connecting to.

So I've picked my way through the socketio.Server() and engineio.Server() guts, I'm struggling to get my head around where's the best place to implement it... I thought I might be able to hijack the namespace and inject the host-name into the namespace a little e.g /unicorns.hostname.com. Except I won't be able to connect the messages to the clients since the namespace is intrinsically hard-coded...

Is there a simpler solution? if not, would you be able to suggest a route I should look at?

From what I can see namespace is only really a function of socketIO and engineIO doesn't care really... but I was hoping for some pointers.

~ Rich

Not every messages are sent from server

Hi! I headed to this library after an unsuccessful attempt with Flask SocketIO, yet the same problem remains. I am trying to display real time tweets through sockets connection, but I am unable to do so. Here is the server implementation :

@sio.on('handshake')
def handshake(sid,data):
    print('handshaked!')
    print(sid)
    client_sid = sid
    sendMessage("Starting to connect with Twitter")
    sendMessage("...")
    startStreaming()
    sendMessage("Started streaming...")

def sendMessage(message):
    print 'sending message' + message
    sio.emit('message',{"data" : message})

def startStreaming():
    sendMessage("Connected")
    ts = TwitterStream(auth=OAuth(token_key,token,con_key,con_secret))
    iterator = ts.statuses.filter(follow=37034483)
    for tweet in iterator:
        tweetBody = json.loads(json.dumps(tweet))
        print(tweetBody["text"])
        sendMessage(tweetBody["text"])

if __name__ == "__main__":
    app = socketio.Middleware(sio, app)
    eventlet.wsgi.server(eventlet.listen(('', 5000)),app)

And the client is a simple listener :

var socket = io.connect('http://' + document.domain + ':' + location.port)
  socket.on('connect', function () {
      socket.emit('handshake', { data : 'connected'})
  })
  socket.on('message', function (tweet) {
    console.log(tweet)
    $(".messages").append("<p>" + tweet.data + "</p>")
  })

Now the issue is that, after initial handshake, the server is posting the first two messages "Starting to connect with Twitter" and "...", but soon after it doesn't even post the subsequent messages, not even "Connected", and the logs show that I am receiving twitter streams. I have tried every iteration, and even using Flask SocketIO global broadcast socketio.emit but of no use. Please suggest alternatives. (P.S. I am new in python)

Can not send arrays/lists of objects/dicts as reply to a message

I'm using Flask-SocketIO for this, but I believe the issue lies within python-socketio. Note that according to this page sending arrays should be supported.

Basically, I want to reply to an event with a list of dicts (in Python), but in the client code I only ever receive the first object in the list as the value and not the list itself. I analyzed the data sent over network and it appears that the list's elements do get sent, but probably not correctly.

What a normal "object" looks like in network: 1[{"playlist":1001,"songs":[...]}]
What the list of an object looks like: ๏ฟฝรฟ432[{"id":1000,"name":"Playlist001"},{"id":1001,"name":"Playlist002"}]

I belive that python-socketio does not consider arrays when packing data and the client implementation only parses an object inside the brackets, but not the brackets themselves. Please correct me if I'm wrong.

Unfortunately I am not able to provide sample code at this moment.

server needs to be killed twice when using client_manager

my script is like this:

#!/usr/bin/env python2

import socketio
import eventlet
eventlet.monkey_patch()

mgr = socketio.KombuManager()
sio = socketio.Server(async_mode='eventlet', client_manager=mgr)   

if __name__ == '__main__':
    app = socketio.Middleware(sio)
    eventlet.wsgi.server(eventlet.listen(('', 8000)), app)

on startup it prints

(29745) wsgi starting up on http://0.0.0.0:8000

after one ^C I have

^Cwsgi exiting
(29745) wsgi exited, is_accepting=True

but it hangs. I have to ^C again to get

^CException KeyboardInterrupt: KeyboardInterrupt() in <module 'threading' from '/usr/lib64/python2.7/threading.pyc'> ignored

and then it returns me to my shell.

this two step process makes it harder to run under a process manager that wants to be able to kill its children cleanly.

the issue does not exist if i remove the client_manager argument.

get_participants does not list users connected to a different server

I successfully implemented a modified version of Flask-SocketIO-Chat which allows users connected to different ports (in my case, 5001 and 5002) but in the same namespace and room to communicate using a kombu_manager. However, it looks like theclient_manager for each of the servers maintains a separate list of connected users. (I'm accessing the list of users using socketio.server.manager.get_participants(). Is this the expected behavior?pubsub_manager.py suggests that any class that implements it should be able to share the full list of clients.

I can provide more details and a minimal working example if necessary, but I wanted to check whether the list of users is intended to be shared (via get_participants()) first.


To give a bit more detail, the code for handling events in this section was replaced by the following:

@benchling_socketio.on('text', namespace='/chat')
def text(message):
    """Sent by a client when the user entered a new message.
    The message is sent to all people in the room."""
    room = session.get('room')
    emit('message', {'msg': session.get('name') + ':' + message['msg']}, room=room)
    if message['msg'] == 'list-all-users':
        participants = list(benchling_socketio.server.manager.get_participants(namespace='/chat', room=room))
        emit('message', {'msg': u'Total number of participants is {}'.format(len(participants))}, room=room)
        emit('message', {'msg': 'Current user ids of users in room are ...'}, room=room)
        for participant in participants:
            emit('message', {'msg': u'  {}'.format(participant)}, room=room)

Examples of the app in use are shown:

screen shot 2016-07-11 at 7 17 28 pm

Spawned emitting - class based namespace - thread still alive

Hi @miguelgrinberg ,
maybe it's related to gevent.spawn but having a strange behaviour while emitting from a class namespace (working on gevent supervisored):

on user connection we set a connected = True, send a welcome message (using room = sid too) then we gevent.spawn a func; this func emits to connected client (always using its sid) and has a gevent.sleep(x) to autoemit under a while connected statement. On disconnect we set our connected = False, client get disconnected, and here comes the fun:
if user move to another backbone view then back to that page all is ok (client connects, client disconnects, new client connection)
if user refresh (F5) our page client disconnects, new client connection, but process is alive and emitting.

Maybe related to handling page refresh? probably, but this doesn't solve the infinite emits against a disconnected client

Mirko

Working with sockets from wsgi app

Hello!
I am trying to work with sockets from django app. I don't understand how can I possibly access to sockets from django. For example, I have request in django that creates some obkects and I want tu brodcast this object to all of the clients. Could you give a hint, please?

ValueError: invalid literal for int() with base 10: b'%'

I'm sorry but it seems that your measure discussed in here #37 did not entirely fix the problem.
I continued implementing my frontend part and now problems occurred again.

Exception in thread Thread-27:
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/threading.py", line 862, in run
    self._target(*self._args, **self._kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/socketio/server.py", line 444, in _handle_eio_message
    pkt = packet.Packet(encoded_packet=data)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/socketio/packet.py", line 33, in __init__
    self.attachment_count = self.decode(encoded_packet)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/socketio/packet.py", line 74, in decode
    self.packet_type = int(ep[0:1])
ValueError: invalid literal for int() with base 10: b'%'

Strange: if I print the payload the library tries to decode it's not even a binary string. It's some other request. So if there are many requests - some having binary content in a dictionary and some having only string content in a dictionary - there seems to be a confusion about the different requests.

Python-SocketIO server won't emit from the main section of the program

I have a pyhton-socketio server that servers on port 8000 and handles connections perfectly. I want to emit the following emit message every 2 seconds. When emitting the client doesn't receive a message. If I emit from where I point out in the comment it works perfect.

How can I edit this to be able to emit from inside the while loop successfully?

The python server code:

import socketio
import eventlet
import threading
import time
from flask import Flask, render_template

sio = socketio.Server()
app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index.html')


# as a decorator:
@sio.on('connect')
def connect_handler(sid, environ):
    print('IP->' + environ['REMOTE_ADDR'])
    # If I emit here it works e.g. sio.emit('status-update', {'core0_in': 8, 'core1_in': 12,'cpu_usage_in': 5, 'users': 7})


@sio.on('disconnect')
def disconnect(sid):
    print('disconnect ', sid)


class Server(threading.Thread):
    def __init__(self, thread_id):
        threading.Thread.__init__(self)
        self.threadID = thread_id

    def run(self):
        print("Starting " + self.name)
        serve()


def serve():
    if __name__ == '__main__':
        global app
        # wrap Flask application with socketio's middleware
        app = socketio.Middleware(sio, app)

        # deploy as an eventlet WSGI server
        eventlet.wsgi.server(eventlet.listen(('', 8000)), app)


server_thread = Server("Server-thread")
server_thread.start()
while True:
    print("Emitting...")
    sio.emit('status-update', {'core0_in': 8, 'core1_in': 12,'cpu_usage_in': 5, 'users': 7})  # when emitting here the client doesn't receive anything
    time.sleep(2)

Interoperability with node.js socket.io client

I'm having lots of problems getting an official node.js socket.io client connected to a python-socketio server. This is the client library I'm using: https://github.com/socketio/socket.io-client

I've tried both python-socketio and flask-socketio, and in both cases, I get log output from the web server and from the connect() handler, but the client never runs its connect() handler or emits any messages.

Flask-SocketIO Server:

from flask import Flask
from flask_socketio import SocketIO

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)


@socketio.on('test')
def handle_message(message):
    print('received test: ' + message)


@socketio.on('connect')
def test_connect():
    print('got a connect')
    socketio.emit('my response', {'data': 'Connected'})


if __name__ == '__main__':
    socketio.run(app, port=3000)

python-socketio server:

import socketio
import eventlet
from flask import Flask, render_template

sio = socketio.Server()
app = Flask(__name__)


@app.route('/')
def index():
    """Serve the client-side application."""
    return render_template('index.html')


@sio.on('connect')
def connect(sid, environ):
    print('connect ', sid)
    return True


@sio.on('test')
def message(sid, data):
    print('looking at test ', data)


@sio.on('disconnect')
def disconnect(sid):
    print('disconnect ', sid)

if __name__ == '__main__':
    # wrap Flask application with socketio's middleware
    app = socketio.Middleware(sio, app)

    # deploy as an eventlet WSGI server
    eventlet.wsgi.server(eventlet.listen(('', 3000)), app)

Node.js Client:

//client.js
var io = require('socket.io-client');
var socket = io.connect('http://localhost:3000', {reconnect: true});

// Add a connect listener
socket.on('connect', function () {
    console.log('Connected!');
    socket.emit("test", {"data":"blob"});
});
socket.emit('CH01', 'me', 'test msg');

Node.js Socket.IO Server (works):

//server.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

io.on('connection', function (socket){
   console.log('connection made');

  socket.on('CH01', function (from, msg) {
    console.log('MSG', from, ' saying ', msg);
  });

  socket.on('test', function (from, msg) {
    console.log("we got test");
  });

});

http.listen(3000, function () {
  console.log('listening on *:3000');
});

Best practice: Emitting on ZMQ event received in separate thread

Hey everyone,

this is rather a general question than an issue...
I'm getting started in Python and Flask / Flask-SocketIO, so please excuse me, if the question or my understanding are lacking basic things... (If possible, just point me in the right direction).

I'm working on the following application and so far, I've seen a multitude of differnt options on how to implement it and between changes between versions, I'm about to get (very) lost..
I'm not specifically looking for code, I'm more interested in the idea I should pursue and why...

At the core of my system is a Raspberry Pi with Tinkerforge modules (https://www.tinkerforge.com) attached to record humidity and various other sensors. I'm obtaining measurements from these modules at a fixed rate of every second. Then these measurements are saved in a sqlite3 db and published via a ZeroMQ (http://zeromq.org/) publisher.
Works like a charm !! I can even access the values, published via ZMQ, from LabVIEW !!

Now comes the part that gives me trouble...
I would like to present the recorded values in some kind of live-dashboard...
Naturally the idea would be to also run the necessary server on the RPi and only connect with some frontend, if interested in the values... And having worked alittle with NodeJS before, I started looking at SocketIO for on the fly updates... (This way I could also later run the server on a more powerful system, if the RPi is too weak or otherwise occupied doing more important stuff.. That's why I kept the recording/saving/publishing separate from the visual presentation)
I got the system to work smoothly, for what I have in mind as follows:
Separately from the Python program, that records the measurements and publishes as ZeroMQ messages, I wrote a Flask-SocketIO server (NO eventlet / gevent installed)..
This program spawns a separate thread (import threading), that connects to the ZMQ publisher and waits to receive a message from the separate code via ZMQ Publish.
When a ZMQ message is received, the SocketIO emits with a custom event (correct term?).
This custom event is received from the SocketIO.js in the webpage and processed, added to a graph and the graphs on the page are updates (graphs with Highcharts.js)
Perfect, but ...
Looking at the log outputs, I saw a lot of "polling" mentioned and started to look into that further...
After installing eventlet nad changing the code to use eventlet, even if Debug = True, I got the page to load, but no SocketIO updates... until I inserted a "time.sleep" in the emitting function... (not necessary before with no eventlet...).
In my reverse-engineering understanding, this is necessary for the threading to work properly and have the main thread running the Flask-SocketIO server being able to actually emit what was given to it by the separate thread to emit.. Why doesn't this happen when using Werkzeug? (Because of polling?)

In my understanding, this leaves me with a forced sleep there to run via eventlet, that is not necessary when using the Flask development server Werkzeug... I don't like "Magic Delay Fairies".. But I get the feeling that this is due to me not understanding something properly...

Based on the description of my system above, what is the favorable way to implement the ZMQ event-driven emission of SocketIO "messages"?

Please find my code attached (Directly incorporating screwed up the Markdown and attaching py-files didn't work either, so they became text files..)

Cheers
Niels Gรถran

system_core - Record data, save to DB and ZMQ publish
system_core.txt

server - ZMQ event-driven emission of SocketIO
server.txt

Emit in a room raises RuntimeError

Hi there, I've been running into the following recently, could you take a look please

    File "/Users/marty/site/flask-socketio/venv/lib/python3.4/site-packages/socketio/server.py", line 181, in emit
      self.manager.emit(event, data, namespace, room, skip_sid, callback)
    File "/Users/marty/site/flask-socketio/venv/lib/python3.4/site-packages/socketio/base_manager.py", line 97, in emit
      for sid in self.get_participants(namespace, room):
    File "/Users/marty/site/flask-socketio/venv/lib/python3.4/site-packages/socketio/base_manager.py", line 30, in get_participants
      for sid, active in six.iteritems(self.rooms[namespace][room]):
  RuntimeError: dictionary changed size during iteration

Seems to only happen when I need to run an .emit on 'disconnect' of a different client.

missing git release tag for 1.2

Hey, as a package maintainer I'm having an upstream watch onto this git repository, this is incredibly convenient. Unfortunately the 1.2 version tag was missing, therefor I missed the 1.2 release and updated from 1.1 to 1.3.
Could you please push the missing 1.2 tag and maybe try to make sure they will not be missing? ๐Ÿ˜ธ

Add support for per socket event handling and emitting

The node.js version of socket.io has support for adding event handlers at the socket/connection level vs the server level.

var io = require('socket.io')(80);

io.on('connection', function (socket) {
  io.emit('this', { will: 'be received by everyone'});

  socket.on('private message', function (from, msg) {
    console.log('I received a private message by ', from, ' saying ', msg);
  });

  socket.on('disconnect', function () {
    io.emit('user disconnected');  // broadcast event 'user disconnected'
  });
});

It would be nice if this python library supported the same ability as well. This would allow point-to-point communication between the server and the clients when necessary.

Socket disconnect event not always fired

Hi Miguel,

Let me first thank you for all the great work you've done on this library!

I am experiencing some strange behavior in which sockets are not closed approximately 10% of the time. I am actively logging all the socket sessions in a database: I insert the socketid with starting timestamp on the connect event, and update the end timestamp when the disconnect event is fired. From the DB logs I can see some sockets are never closed, and the Heroku logs do indeed confirm this (I have added a print statements on the connect and disconnect events). A failed socket typically has the following log trail:

Aug 07 07:25:40 ancient-ravine-83370 heroku/router: at=info method=POST path="/socket.io/?EIO=3&transport=polling&t=1470579937315-1&sid=63ac83da17d74da88a2e290c4be0a8b1" host=ancient-ravine-83370.herokuapp.com request_id=94b6c8d3-bc9d-4140-9318-9de14bff3f3d fwd="180.215.121.1" dyno=web.1 connect=0ms service=2ms status=200 bytes=277 
Aug 07 07:25:40 ancient-ravine-83370 app/web.1: add: 63ac83da17d74da88a2e290c4be0a8b1 
Aug 07 07:25:40 ancient-ravine-83370 heroku/router: at=info method=GET path="/socket.io/?EIO=3&transport=polling&t=1470579937362-2&sid=63ac83da17d74da88a2e290c4be0a8b1" host=ancient-ravine-83370.herokuapp.com request_id=b3506d6e-5842-479e-9e23-f7aecd9bb582 fwd="180.215.121.1" dyno=web.1 connect=1ms service=2ms status=200 bytes=266 
Aug 07 07:25:40 ancient-ravine-83370 heroku/router: at=info method=GET path="/socket.io/?EIO=3&transport=websocket&sid=63ac83da17d74da88a2e290c4be0a8b1" host=ancient-ravine-83370.herokuapp.com request_id=80e5527e-5c5b-4331-82fb-61899ba74d6a fwd="180.215.121.1" dyno=web.1 connect=0ms service=817ms status=101 bytes=129 

For your information, the app is deployed on Heroku with the following requirements.txt:

eventlet==0.18.4
Flask==0.10.1
Flask-HTTPAuth==3.1.2
Flask-SQLAlchemy==2.1
gunicorn==18.0
PsiTurk==2.1.2
psycopg2==2.6.1
python-engineio==0.9.2
python-socketio==1.4.2
requests==2.9.1
user-agents==1.0.1

Not sure how I could debug this issue further as there is no error popping up in the Heroku logs directly related to this issue. I do see some H12 timeout issues from time to time but I do assume these are coming from long-polling?

Thanks,
Harm

Invalid async_mode specified

hello!
Everything was OK when I run my python file, but it raised error run after be packed with pyinstaller:

Traceback (most recent call last):

  File "ems\core\task.py", line 67, in add
  File "ems\ems_socket_service.py", line 26, in __init__
  File "site-packages\socketio\server.py", line 72, in __init__
  File "site-packages\engineio\server.py", line 100, in __init__
ValueError: Invalid async_mode specified

the code :self.socketio = socketio.Server(async_mode='gevent')

I tried self.socketio = socketio.Server(), it's also useless, and i have installed gevent.

About renaming the python-socketio library

Hi,
I'm currently packaging python-socketio for debian and I'm facing the following problem :
there's already a package named python-socketio in Debian :

Debian package : https://packages.debian.org/unstable/python-socketio
Upstream project : https://github.com/abourget/gevent-socketio

I could renamed you package's name in debian, but your python library would still want to install in
/usr/lib/python2.7/dist-packages/socketio which is already used by package python-socketio from gevent-socketio.
So the python library name "socketio" is the problem.
From the few that I read, your library does not provide the same interface as gevent-socketio, so I can't
make both an alternative to each other in debian with a "Conflicts" keyword, meaning that users can install one package at a time in the filesystem and use them indifferently as they provide the same interface.
According to Github metric, gevent-socketio as 999stars and python-socketio has 89, which could mean that less projects are impacted by your python-socketio at the moment (I don't have other metric :) so I could actually be wrong here of course)
My question is, what would you think of renaming "socketio" and maybe "python-socketio" so that both
projects don't collide anymore in the python libraries namespace ?
Thanks for your thoughts on this,

Fred

Typo in the documentation

I think in this example second function must be decorated with @sio.on('leave room') instead of @sio.on('enter room').

@sio.on('enter room')
def enter_room(sid, data):
    sio.enter_room(sid, data['room'])

@sio.on('enter room')
def leave_room(sid, data):
    sio.leave_room(sid, data['room'])

Fresh install errors when websocket connection is opened.

I just did a fresh install in my testing VM, and now every time I try to establish a websocket connection, it fails:

192.168.1.106 - - [29/Dec/2015 16:20:43] "GET /socket.io/?EIO=3&transport=websocket HTTP/1.1" 500 -
Error on request:
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/werkzeug/serving.py", line 194, in run_wsgi
    execute(self.server.app)
  File "/usr/local/lib/python3.4/dist-packages/werkzeug/serving.py", line 182, in execute
    application_iter = app(environ, start_response)
  File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.4/dist-packages/flask_socketio/__init__.py", line 37, in __call__
    start_response)
  File "/usr/local/lib/python3.4/dist-packages/engineio/middleware.py", line 47, in __call__
    return self.engineio_app.handle_request(environ, start_response)
  File "/usr/local/lib/python3.4/dist-packages/socketio/server.py", line 303, in handle_request
    return self.eio.handle_request(environ, start_response)
  File "/usr/local/lib/python3.4/dist-packages/engineio/server.py", line 217, in handle_request
    transport, b64)
  File "/usr/local/lib/python3.4/dist-packages/engineio/server.py", line 308, in _handle_connect
    s.handle_get_request(environ, start_response)
  File "/usr/local/lib/python3.4/dist-packages/engineio/socket.py", line 75, in handle_get_request
    start_response)
  File "/usr/local/lib/python3.4/dist-packages/engineio/socket.py", line 108, in _upgrade_websocket
    self.server.async['websocket_class'])
TypeError: getattr(): attribute name must be string

I'm going to see if I can figure out what's going on, but this is on a fresh install via pip3 install python-socketio

Hangs on connection with some socket-io clients

I'll reference this bug report for socketIO-client: Issue 118.

It appears that if a 'connect' event is captured on the server, and during its execution it emits another event, that some clients will struggle to connect. Tested with both the pythong socket-IO client and a dotnet client.

As 'connect' is a special event, returning False will cause a client to be disconnected. This means that any events that happen in it are added to the packet queue, and only once the event completes does the CONNECT packet get added. These other clients are only expecting the CONNECT and get confused with the event packets coming through.

Removing any emits from my connect handler fixes the python client. And applying a few small patches to handle Content-Type better (depending on b64 flag) fixes the dotnet client as well.

Socket io client receives "connection closed by server" message

I am trying to upload a file from socket-io-client to python server using websocket. I am able to upload file sometimes successfully but most of the time i receive above error message.

I am sharing client and server code.

Can you please help me out to figure this issue?. I had turned on logger=True, engineio_logger=True but could not get information why client connection was disconnected.

Client code:

constructor () {
  super();
  //this.socket = new SocketIO('54.186.174.180:8082', {forceWebsockets:true});
  /*, "reconnects": false,
  "reconnectAttempts": 0 */
  this.socket = new SocketIO('127.0.0.1:5000', {forceWebsockets:true});
  this.state = { avatarSource :'http://iphonewallpapers-hd.com/thumbs/firework_iphone_wallpaper_5-t2.jpg' };
}

componentDidMount () {
  console.log("mount");
  this.socket.on('connect', () => {
    console.log("connected");
    this.setState({
      status: 'Connected'
    });
  });

  this.socket.on('error', (error) => {
    console.log('error')
    console.log(error);
    this.setState({
      status: 'error'
    });
  });

  this.socket.on('responseevent', (responseevent) => {
    console.log(responseevent);
  });

  console.log("connect");
  this.socket.connect();
}

onLoadPress() {
      PhotoLibrary.readPhoto(
          (results) => {
              console.log(results)
              this.setState({avatarSource:results.imageUrl});

             RNFS.readFile(results.imageUrl).then((contents) => {
               this.socket.emit('userimage', {
                 imageData: contents
               });
              })
              .catch((err) => {
                console.log("error reading file");
                console.log(err.message, err.code);
              });
          },
          (results) => {
              alert('callback2' );
          }
      );
}

Python server code.

import socketio
import eventlet
from flask import Flask
from flask_socketio import emit


sio = socketio.Server(logger=False, engineio_logger=False)
app = Flask(__name__)



@sio.on('connect')
def test_connect(arg1, arg2):
    print('Client connected')
    sio.emit('message', {'data': 'Connected'})

@sio.on('error')
def test_connect(arg1, arg2):
    print('error')
#    sio.emit('message', {'data': 'Connected'})

@sio.on('userimage')
def testuserimage(arg1, arg2):
    print('userimage')

@sio.on('randomEvent')
def testemit(arg1, arg2):
    print(arg2)
    sio.emit('responseevent', {'hi':'manju'})

@sio.on('disconnect')
def test_disconnect(arg):
    print('Client disconnected')

if __name__ == '__main__':
    # wrap Flask application with engineio's middleware
    app = socketio.Middleware(sio, app)

    # deploy as an eventlet WSGI server
    eventlet.wsgi.server(eventlet.listen(('127.0.0.1', 5000)), app)    

In python console i receive this message after a while
Traceback (most recent call last):
File "/Users/manjurn/virtualEnv/sandalmatching/lib/python2.7/site-packages/eventlet/wsgi.py", line 483, in handle_one_response
write(b''.join(towrite))
File "/Users/manjurn/virtualEnv/sandalmatching/lib/python2.7/site-packages/eventlet/wsgi.py", line 426, in write
_writelines(towrite)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 338, in writelines
self.flush()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 307, in flush
self._sock.sendall(view[write_offset:write_offset+buffer_size])
File "/Users/manjurn/virtualEnv/sandalmatching/lib/python2.7/site-packages/eventlet/greenio/base.py", line 376, in sendall
tail = self.send(data, flags)
File "/Users/manjurn/virtualEnv/sandalmatching/lib/python2.7/site-packages/eventlet/greenio/base.py", line 359, in send
total_sent += fd.send(data[total_sent:], flags)
error: [Errno 32] Broken pipe

Thanks and Regards
Manjunath

is it possible to use this in asyncio?

I want to integrate this into an asynchronous program, when the on_ready event is called I want to call coroutines on socket events. is that possible?

Failing for iOS 5 Safari - Something is causing a hang

When I try my sockio project using python-socketio, it works in all browsers that Ive tried it on except for safari on an iPhone5. It fails there in both a real iPhone5 device as well as apple's iOS simulator. i cant figure out how to debug it. the problem commonly happens when you first load my socket io app .. and i think the problem relates to the code that manages the pausing and connection upgrading.

I believe that the problem relates to this library since the iOS 5 demos work on http://socket.io/ so deductive reasoning tells me there's something causing this from within python-socketio.

Can someone comment on how the pausing/upgrading is supposed to work and explain why perhaps it seems to hang on iOS5 Safari?

client_manager hangs

when i have this, from the docs:

mgr = socketio.KombuManager('redis://')
sio = socketio.Server(client_manager=mgr)

the second line hangs. it works without the keyword argument. I have made sure that reddis and rabbitmq are running and have tried variations on the URI on the first line without success.

can anyone offer any suggestions on diagnosing the problem?

requires pinned dependency version pbr<1.7.0

pbr has already released its 1.8.1 version, is the bug that made you pin pbr for socketio fixed there? If yes, could you please change the pinning of the required version? I'm planning to package this library for a distribution where we only ship the most current version of everything

Leaving and re-entering a room can cause incorrect room state

It seems there is an issue with BaseManager.pending_removals getting stale and causing the removal of a user from a room they should be in.

Example (Imagine the various leave/enter/emit calls being spread out over time and multiple requests):

server = ... # Socket.IO Server
room = 'my room'
session_id = ... # Current session id for one user

# Enter room normally
server.enter_room(session_id, room)  

 # Leave room normally, server.manager.pending_removals populated
server.leave_room(session_id, room) 

# Re-enter room, server.manager.pending_removals still populated
server.enter_room(session_id, room)     

# Message emitted, followed by server.manager.pending_removals being processed internally
server.emit('something', 'data', room=room)     

# Message *NOT* emitted, because the room was removed after the previous emit
server.emit('something else', 'data', room=room)

The workaround was to do:

server = ... # Socket.IO Server
room = 'my room'
session_id = ... # Current session id for one user

# Enter room normally
server.enter_room(session_id, room)  

 # Leave room normally, server.manager.pending_removals populated
server.leave_room(session_id, room) 

# WORKAROUND: Force clean-up of old removals before entering the new room
server.manager._clean_rooms()

# Re-enter room, server.manager.pending_removals is now clear
server.enter_room(session_id, room)     

# Message emitted normally
server.emit('something', 'data', room=room)     

# Message emitted normally
server.emit('something else', 'data', room=room)

This leads me to believe that the fix is likely something that needs to be added to enter_room( ... ) that reconciles the new subscriptions to a given room with the previous, perhaps unreconciled, room evictions in BaseManager.pending_removals.

Event name with dash causes crash in Python 3.5

Running flask-socket-io using Python 3.5 I ran into the following issue when trying to send a message with an event name containing a dash.

From .js client:

socket.on('connect', function() {
    socket.emit('connect-event', {data :  'Client connected'});
});

Error in Python 3.5
ValueError: invalid literal for int() with base 10:

Points to:
packet.py line 84

How Do I Use the Redis Feature?

Hello,

I am attempting to use the socketio package to create a LiveReloaded web server of sorts. As you can imagine with several different loops running at once (one running the web server, one watching files for changes, and also a WebSocket server) it would be wise to use the Redis feature of Python-SocketIO.

Unfortunately, it does not seem to be that easy. So I have a few questions. But first, here is my current code:

My Server

import eventlet
import socketio

class ExampleNamespace(socketio.Namespace):
    def on_connect(self, sid, environ):
        stringy = "YO, {} connected!".format(sid)
        print(stringy)
        self.send(stringy)

    def on_message(self, sid, data):
        self.send(data)

manager = socketio.RedisManager()
socket_server = socketio.Server(client_manager=manager)
socket_server.register_namespace(ExampleNamespace())

app = socketio.Middleware(socket_server)
eventlet.wsgi.server(eventlet.listen(('', 8000)), app)

My client

<!DOCTYPE html>
<html>
  <head>
    <title>Socket.IO Test</title>
  </head>
  <body>
    <ul></ul>
    <!-- I have a local copy of the socket.io Javascript -->
    <script src="./socket.io-1.4.6.js"></script>
    <script>
      var socket = io('http://0.0.0.0:8000');
      socket.on('message', function (data) {
        console.log(data);
        // Create some elements
        var messages = document.getElementsByTagName('ul')[0],
          message = document.createElement('li'),
          content = document.createTextNode(data);
        // Add the crap to the elements
        message.appendChild(content);
        messages.appendChild(message);
      });
    </script>
  </body>
</html>

So here is where I am at:

  • When I added the client_manager keyword to the socketio.Server class, it no longer functions. But if I leave it out, then the server sends messages perfectly to the client when a new client joins, like it should. And yes, I am running a Redis server.
  • I am not entirely sure as to what happens to a message once I send it over the Redis message queue. Let's say while my Socket.IO server is running (correctly) and I have a Redis server open, what happens if I run the code below in my interpreter? Does this make it to the server? And how do I decide what my server does with this data? Is there a specific "on_" method I should add to my namespace?
>>> import redis
>>> r = redis.StrictRedis()
>>> p = r.pubsub()
>>> p.subscribe('socketio')
>>> r.publish('socketio', 'Hello World')
1 
  • As a little bit of a side question, do I need to use Eventlet to run a Socket.IO server? I am not really using any of Eventlet's concurrency features (directly). Is there some way I could use Python's built in web server or Twisted?

Client not finding Socket.IO server

I'm using Flask with uWSGI and NGINX, having set up the Socket.IO server as sio = socketio.Server(async_mode='gevent_uwsgi', logger=True). The whole thing is running in a Docker container which listens on localhost port 3536.

On the client side, I have JS which sends socket requests to Socket.IO. On all requests Chrome shows 404 NOT FOUND, while server logs don't show nothing at all.

For instance, I have this thing on server side:

@sio.on('process_registration', namespace='/regauth')
def process_registration(sid, message):
    <...>

And this on the client:

<script type="text/javascript">
      /* global io, grecaptcha, $ */
      namespace = "/regauth";
      var socket = io.connect('http://' + document.domain + ':' + location.port + namespace);

      $('#register-send_btn').click(function() {
           var username = $('#register-username').val(),
               pwd = $('#register-pwd').val(),
               pwd_confirm = $('#register-pwd_confirm').val(),
               email = $('#register-email').val(),
               grecaptcha_response = $('#register-grecaptcha_response').val();

           socket.emit("process_registration", {
               uname: username,
               password: pwd,
               password2: pwd_confirm,
               email: email,
               recaptcha_response: grecaptcha_response
           });
    });
</script>

The error I'm getting is:

socket.io.js:4196 GET http://127.0.0.1:3536/socket.io/?EIO=3&transport=polling&t=LX4DrIW 404 (NOT FOUND)

It seems either that the browser ignores the io.connect('http://' + document.domain + ':' + location.port + namespace); line because requests are still sent to /socket.io, or the server is not listening. Help me, please :)

Handling of binary data fails sometimes

After updating flask-socketio from 1.2 to 2.6 I have a strange error that comes up occasionally when there are more than a few threads that handle a binary message from a socket.io client. I get the following error:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/threading.py", line 862, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/maRcbook/Library/Python/3.5/lib/python/site-packages/socketio/server.py", line 442, in _handle_eio_message
    self._binary_packet.reconstruct_binary(self._attachments)
AttributeError: 'NoneType' object has no attribute 'reconstruct_binary'

I just noticed is has nothing to do with the upgrade of flask-socketio. I upgraded python from 3.4 to 3.5 as well and this is probably the cause. Downgrading flask-socketio did not make it work. So it probably has to do with python-socketio for python 3.5

Flask session support

Currently, we can't store anything from the client into the Flask session. Here is a traceback of the issue when trying to use it:

Traceback (most recent call last):
  File "/home/tito/.virtualenvs/new-socketio/local/lib/python2.7/site-packages/eventlet/wsgi.py", line 454, in handle_one_response
    result = self.application(self.environ, start_response)
  File "/home/tito/.virtualenvs/new-socketio/local/lib/python2.7/site-packages/engineio/middleware.py", line 32, in __call__
    return self.engineio_app.handle_request(environ, start_response)
  File "/home/tito/.virtualenvs/new-socketio/local/lib/python2.7/site-packages/socketio/server.py", line 253, in handle_request
    return self.eio.handle_request(environ, start_response)
  File "/home/tito/.virtualenvs/new-socketio/local/lib/python2.7/site-packages/engineio/server.py", line 186, in handle_request
    socket.handle_post_request(environ)
  File "/home/tito/.virtualenvs/new-socketio/local/lib/python2.7/site-packages/engineio/socket.py", line 80, in handle_post_request
    self.receive(pkt)
  File "/home/tito/.virtualenvs/new-socketio/local/lib/python2.7/site-packages/engineio/socket.py", line 42, in receive
    self.server._trigger_event('message', self.sid, pkt.data)
  File "/home/tito/.virtualenvs/new-socketio/local/lib/python2.7/site-packages/engineio/server.py", line 240, in _trigger_event
    return self.handlers[event](*args)
  File "/home/tito/.virtualenvs/new-socketio/local/lib/python2.7/site-packages/socketio/server.py", line 394, in _handle_eio_message
    self._handle_connect(sid, pkt.namespace)
  File "/home/tito/.virtualenvs/new-socketio/local/lib/python2.7/site-packages/socketio/server.py", line 284, in _handle_connect
    self.environ[sid]) is False:
  File "/home/tito/.virtualenvs/new-socketio/local/lib/python2.7/site-packages/socketio/server.py", line 345, in _trigger_event
    return self.handlers[namespace][event](*args)
  File "/home/tito/code/ninchanese-app/ninchanese/views/stream.py", line 40, in io_connect
    user_id = session.get("user_id")
  File "/home/tito/.virtualenvs/new-socketio/local/lib/python2.7/site-packages/werkzeug/local.py", line 338, in __getattr__
    return getattr(self._get_current_object(), name)
  File "/home/tito/.virtualenvs/new-socketio/local/lib/python2.7/site-packages/werkzeug/local.py", line 297, in _get_current_object
    return self.__local()
  File "/home/tito/.virtualenvs/new-socketio/local/lib/python2.7/site-packages/flask/globals.py", line 20, in _lookup_req_object
    raise RuntimeError('working outside of request context')
RuntimeError: working outside of request context

Emit from background thread in python

I have a flask server, which has HTTP routes, and SOCKET routes, and the websocket works fine like this. I can receive and emit events.

I am using python-socketio so I can get the sid on every request inbound - instead of using Flask-SocketIO.

I also have a permanently running background thread in the flask server, which does some custom polling, and when it gets data, it needs to emit a message from within the thread, to the sid provided as part of the data that is polled.

When I try this, it seems as if the socket cannot emit because it is out of context.

When I was writing this at first, I managed to emit from within a thread, and from HTTP routes, but that was using Flask-SocketIO, which I am trying to avoid, as I need to be able to get the sid from every incoming request as a string.

Any advice?

RuntimeError: Second simultaneous read on fileno

app = Flask(__name__)
mgr = socketio.KombuManager('amqp://')
sio = socketio.Server(client_manager=mgr, async_mode='eventlet')

Does not seem to work for me.

RuntimeError: Second simultaneous read on fileno ....

I launch the app with:

if __name__ == '__main__':
    # wrap Flask application with socketio's middleware
    app = socketio.Middleware(sio, app)

    # deploy as an eventlet WSGI server
    eventlet.wsgi.server(eventlet.listen(('', 8000)), app)

I would more than welcome any pointers to where I have messed up.

wsgi exit

We created our service with code like in example at project github home page, and it's work fine but periodically application fails with wsgi exiting.

95.181.53.210,127.0.0.1 - - [09/Oct/2016 08:25:24] "GET /socket.io/?number=1330&key=1330c&EIO=3&transport=polling&t=LUdUJ_c&sid=78143f0dfa0e46d9ae7984fb9a217ddd HTTP/1.1" 200 210 0.000111
wsgi exiting
80.250.79.172,127.0.0.1 - - [09/Oct/2016 10:08:28] "GET /socket.io/?number=1101&key=1101&EIO=3&transport=websocket&sid=4f9c263a4f8c4807ac872d49184de338 HTTP/1.1" 200 0 17745.802927

By searching 'wsgi exiting', we found this code:

except (KeyboardInterrupt, SystemExit):
    serv.log.info("wsgi exiting")
    break

There were not any KeyboardInterrupt so it's look like there were SystemExit. But how it was done is unclear.

Horizontal Scaling with Redis as Storage Backend

Hello there,

I'm about to step in to contributing to that project but needed to know what were your plans first.

In the docs you say:

A limitation in the current release of the Socket.IO server is that because the clients are randomly assigned to different server processes, any form of broadcasting is not supported. A storage backend that enables multiple processes to share information about clients is currently in development to address this important limitation.

So my proposed solution to that is to implement that storage backend using Redis PUBSUB.
Many others have seen this as the go-to way of doing multi-processing and it has the advantage of offering horizontal scaling. (An example of this can be found HERE with NodeJS)

can't return nothing from an event handler

With the javascript socket.io, if fn is the server's callback question to the client, calling fn() will send a blank response to the client. Is there a way to do that with this library? I've tried all I can think of, but it always sends at least true, false, or null, but never just blank like the original socket.io. Is this a limitation of this library or am I doing something wrong?

Django

Hi ~

This is not an issue or anything, just an idea I'm interested in and I wanna talk about it. I work with Django but I often miss using WebSocket like Socket.IO does. So this module, python-socket.io is pretty interesting for me (and I should say this is an amazing job).

Anyway, I'm trying to find the best way to use this module with Django. First I was thinking about writing a Middleware then later I thought that it might be a better idea to let the developer handle the entry point if we could easily define that entry like a view using the url router provided by Django.

I tried something like that and it seems to work, I might have a wrong idea about how to mix the two together.

@csrf_exempt
def socketio_view(request):
    # instance a new response
    response = HttpResponse(content_type='application/json')

    def start_response(status, headers):
        # inform the headers & status
        # first get the status code as integer
        response.status_code = int(status.split(' ')[0])
        # then inform headers
        for key, value in headers:
            response[key] = value

    # call the socket io request handler
    response.content = sio.handle_request(request.META, start_response)

    return response

I was thinking about setup the socket io server inside the app configuration (AppConfig) of the module.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.