WebSocket connection failed: error during WebSocket handshake: Unexpected response code: 200

1,026 views
Skip to first unread message

flora.xia...@gmail.com

unread,
Jun 24, 2018, 9:36:29 PM6/24/18
to Django developers (Contributions to Django itself)
Hi I am deploying a website with a live discussion feature. On the discussion page, people cannot send messages nor receive messages. In the console, it shows: "WebSocket connection to 'ws://xxxxxxx/room1/' failed: Error during WebSocket handshake: Unexpected response code: 200". 
I don't know where the websocket bug is (or maybe bugs from other sources?). Could you help me with that? Thanks!!!
I am attaching some information that I think might be useful. If you think I miss anything please let me know and I will post it here!


Some information:
- server: Ubuntu 14.04.3
- Nginx
- the command to run the website
uwsgi --socket experiment_platform.sock --module experiment_platform.wsgi --chmod-socket=666 --processes=6
nohup daphne experiment_platform.asgi:channel_layer --port 8000 --bind 0.0.0.0 -v2 &
nohup python manage.py runworker -v2 &

- the log information of uwsg [it keeps updating whether I was trying to send messages or not, trying to establish the connection (I guess?)]
     [pid: 29884|app: 0|req: 12/119] 100.15.133.125 () {52 vars in 1094 bytes} [Mon Jun 25 01:10:57 2018] GET /forum/room1/ => generated 4792 bytes in 63 msecs (HTTP/1.1 200) 3 headers in 102 bytes (1 switches on core 0)
     [pid: 29885|app: 0|req: 23/120] 100.15.133.125 () {52 vars in 1094 bytes} [Mon Jun 25 01:11:32 2018] GET /forum/room1/ => generated 4792 bytes in 59 msecs (HTTP/1.1 200) 3 headers in 102 bytes (1 switches on core 0)

- the log information of runworker [it didn't update when I did the testing on the discussion page trying to send messages]
     2018-06-25 00:22:42,827 - INFO - runworker - Running worker against channel layer default (asgi_redis.core.RedisChannelLayer)
     2018-06-25 00:22:42,828 - INFO - worker - Listening on channels http.request, websocket.connect, websocket.disconnect, websocket.receive

- snippets of settings.py
CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "asgi_redis.RedisChannelLayer",
        "CONFIG": {
                "hosts": [os.environ.get('REDISTOGO_URL', 'redis://localhost:6379')],
        },
        "ROUTING": "experiment_platform.routing.channel_routing",
        #"ROUTING": "waiting_room.routing.channel_routing",
    },
}

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://localhost:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}

- forum/consumers.py
import re
import json
import logging
from channels import Group
from channels.sessions import channel_session
from .models import Discussion, Statement, Vote
from chat.models import Room
from experiment.models import ExpUser,TaskUser, Crowd
from channels.auth import http_session, http_session_user, channel_session_user, channel_session_user_from_http


log = logging.getLogger(__name__)

@channel_session_user_from_http
@channel_session
def ws_connect(message):
    # Extract the discussion-label from the message. This expects message.path to be of the
    # form forum/{label}/, and finds a Discussion if the message path is applicable,
    # and if the Discussion exists. Otherwise, bails (meaning this is a some othersort
    # of websocket). So, this is effectively a version of _get_object_or_404.
    try:
        log.debug('In the try block of ws_connect')#added by me
        prefix, label = message['path'].decode('ascii').strip('/').split('/')

        if prefix != 'forum':
            log.debug('invalid ws path=%s', message['path'])
    
            return
        if prefix == 'forum':
        discussion = Discussion.objects.get(label=label)

    except ValueError:
        log.debug('invalid ws path=%s', message['path'])
        return
    except Discussion.DoesNotExist:
        log.debug('ws discussion does not exist label=%s', label)
        return

    if prefix == 'forum':
        log.debug('forum connect discussion=%s client=%s:%s', discussion.label, message['client'][0], message['client'][1])
        t = TaskUser(user=message.user,crowd=label,time_type='start')
        t.save()
        # Need to be explicit about the channel layer so that testability works
        # This may be a FIXME?
        Group('forum-'+label, channel_layer=message.channel_layer).add(message.reply_channel)
        message.channel_session['discussion'] = discussion.label

    message.reply_channel.send({
        'accept': True
        })


@channel_session_user
@channel_session
def ws_receive(message):
    if 'discussion' in message.channel_session:
    # Look up the room from the channel session, bailing if it doesn't exist
        try:
            label = message.channel_session['discussion']
            discussion = Discussion.objects.get(label=label)
        except KeyError:
            log.debug('no discussion-forum in channel_session')
            return
        except Discussion.DoesNotExist:
            log.debug('recieved message, buy discussion does not exist label=%s', label)
            return

        try:
            expuser = ExpUser.objects.get(user=message.user)
        except KeyError:
            log.debug('problem getting username')
            return
        except ExpUser.DoesNotExist:
            log.debug('recieved message, but user does not exist label=%s', label)
            return


    # Parse out a chat message from the content text, bailing if it doesn't
    # conform to the expected message format.
        try:
            data = json.loads(message['text'])
        except ValueError:
            log.debug("ws message isn't json text=%s", text)
            return
    
    ## check whether it is acceptable format
#    if set(data.keys()) != set(('handle', 'message','isreply','parentid')):
    
    #if set(data.keys()) != set(('handle', 'msg_type')):
    #    log.debug("ws message unexpected format data=%s", data)
    #    return

        if data:
            if data['msg_type'] == 'vote':
                log.debug('vote handle=%s value=%s', 
                expuser.nickname, data['value'])
            
                statement = Statement.objects.get(id=data['id'])
                m0 = statement.as_dict()
                log.debug('vote id=%s, score=%s, ups=%s, downs=%s',statement.id,statement.score,statement.ups,statement.downs)
                
                ndata = {'user':message.user,'handle':expuser.nickname,'statement':statement,'value':data['value']}
                #vote = Vote.objects.create(**ndata)
                #vote = vote.new_vote()
                vote = None
                votes = Vote.objects.filter(user=message.user,statement=statement)
                if not votes:
                    vote = Vote.objects.create(**ndata)
                else:
                    vote = votes[0]
                    vote.value = data['value']
                    vote.save()


                #m = Vote.objects.create(data['handle'],statement,data['value']) # NEED TO FIX HERE
                #vote = Vote.create(handle=data['handle'],
                #               statement=statement,
                #               value=data['value'])
                #vote.save()
                m = statement.update_score()
                m['msg_type'] = 'vote'
                log.debug('vote score=%s', 
                m['score'])

            # See above for the note about Group
                Group('forum-'+label, channel_layer=message.channel_layer).send({'text': json.dumps(m)})

            else:
                log.debug('chat message handle=%s message=%s', 
                expuser.nickname, data['message'])

                parent = None
                log.debug(data['parentid'])
                if data['parentid']!=0:
                    parent = discussion.statements.get(id=data['parentid'])
                    log.debug(parent.id)
                data['parent'] = parent
                data.pop("msg_type",None)
                data['user'] = message.user
                data['handle'] = expuser.nickname

                data['crowd_label'] = discussion.crowd_label
                data['task_label'] = discussion.task_label
                
                m = discussion.statements.create(**data) # NEED TO FIX HERE

                # See above for the note about Group
                Group('forum-'+label, channel_layer=message.channel_layer).send({'text': json.dumps(m.as_dict())})



@channel_session_user
@channel_session
def ws_disconnect(message):
    if 'discussion' in message.channel_session:
        try:
            label = message.channel_session['discussion']
            discussion = Discussion.objects.get(label=label)
#crowd_taskuser = Crowd.objects.get(id=int(label))
            t = TaskUser(user=message.user,crowd=label,time_type='end')
            t.save()
            Group('forum-'+label, channel_layer=message.channel_layer).discard(message.reply_channel)
        except (KeyError, Discussion.DoesNotExist):
            pass

Andrew Godwin

unread,
Jun 24, 2018, 9:56:01 PM6/24/18
to django-d...@googlegroups.com
Hi - this mailing list is for the development of Django itself. You already posted on django-users (the right one) - please don’t double-post!

I’ll get around to replying to that other one in a day or two.

Andrew

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/1e623c3c-e69e-4fce-95d9-7dddb53a177e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Xiaoyun Huang

unread,
Jun 24, 2018, 10:17:03 PM6/24/18
to django-d...@googlegroups.com
Thank you! I posted on django-developer before knowing this question should be posted on django-user so I posted again. I won't doouble-post anymore!  Looking forward to your response! I have been suffered from this bug for a week. :(

To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscribe@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscribe@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages