Hi I am deploying a website with a live discussion feature. But people cannot send nor receive messages on this discussion page. In the console it shows: "WebSocket connection to 'ws://xxxxxxxx/room1/' failed: Error during WebSocket handshake: Unexpected response code: 200"
I don't know where the websocket bug (or bugs from other sources) is. I am attaching some information that I think might be helpful. Could someone help? If you think I miss some information please let me know and I will post! Thanks!!!!!!
Server: ubuntu 14.03
nginx
commands to start the website:
uwsgi --socket experiment_platform.sock --module experiment_platform.wsgi --chmod-socket=666 --processes=6
daphne experiment_platform.asgi:channel_layer --port 8000 --bind 0.0.0.0 -v2 &
python manage.py runworker -v2 &
[redis server is also activated.]
log information of uwsgi (it keeps updating similar things after the discussion page is opened, whether or not I am trying to send messages to test or not. I think it's trying to establish the websocket connection.)
[pid: 29881|app: 0|req: 33/143] 100.15.133.125 () {52 vars in 1094 bytes} [Mon Jun 25 01:23:59 2018] GET /forum/room1/ => generated 4792 bytes in 55 msecs (HTTP/1.1 200) 3 headers in 102 bytes (1 switches on core 0)
[pid: 29885|app: 0|req: 29/144] 100.15.133.125 () {52 vars in 1094 bytes} [Mon Jun 25 01:24:29 2018] GET /forum/room1/ => generated 4792 bytes in 57 msecs (HTTP/1.1 200) 3 headers in 102 bytes (1 switches on core 0)
log information of runworker (it doesn't update after opening the discussion page.)
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
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
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 = 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 = 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)
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
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",
}
}
}