I am trying to use django channels for the first time and i am following the tutorial in the documentation. But when I use python manage.py runserver and try to connect i get this error.
Protocol error, got "H" as reply type byte
Here is the whole console(I'm using anaconda):
Quit the server with CTRL-BREAK.
2018-06-20 15:59:25,665 - INFO - server - HTTP/2 support not enabled (install the http2 and tls Twisted extras)
2018-06-20 15:59:25,665 - INFO - server - Configuring endpoint tcp:port=8000:interface=127.0.0.1
2018-06-20 15:59:25,665 - INFO - server - Listening on TCP address 127.0.0.1:8000
[2018/06/20 15:59:36] HTTP GET /chat/lobby/ 200 [0.12, 127.0.0.1:62590]
[2018/06/20 15:59:36] WebSocket HANDSHAKING /ws/chat/lobby/ [127.0.0.1:62594]
2018-06-20 15:59:37,694 - ERROR - server - Exception inside application: Protocol error, got "H" as reply type byte
File "C:\Users\Pc\Anaconda3\envs\django\lib\site-packages\channels\sessions.py", line 175, in __call__
return await self.inner(receive, self.send)
File "C:\Users\Pc\Anaconda3\envs\django\lib\site-packages\channels\middleware.py", line 41, in coroutine_call
await inner_instance(receive, send)
File "C:\Users\Pc\Anaconda3\envs\django\lib\site-packages\channels\consumer.py", line 54, in __call__
await await_many_dispatch([receive, self.channel_receive], self.dispatch)
File "C:\Users\Pc\Anaconda3\envs\django\lib\site-packages\channels\utils.py", line 50, in await_many_dispatch
await dispatch(result)
File "C:\Users\Pc\Anaconda3\envs\django\lib\site-packages\channels\consumer.py", line 67, in dispatch
await handler(message)
File "C:\Users\Pc\Anaconda3\envs\django\lib\site-packages\channels\generic\websocket.py", line 173, in websocket_connect
await self.connect()
File "C:\Users\Pc\Documents\tutorial\django-channel-tut\chat\consumers.py", line 11, in connect
self.channel_name
File "C:\Users\Pc\Anaconda3\envs\django\lib\site-packages\channels_redis\core.py", line 282, in group_add
channel,
File "C:\Users\Pc\Anaconda3\envs\django\lib\site-packages\aioredis\connection.py", line 181, in _read_data
obj = await self._reader.readobj()
File "C:\Users\Pc\Anaconda3\envs\django\lib\site-packages\aioredis\stream.py", line 78, in readobj
obj = self._parser.gets()
Protocol error, got "H" as reply type byte
[2018/06/20 15:59:37] WebSocket DISCONNECT /ws/chat/lobby/ [127.0.0.1:62594]
On the frontend js return this error
(index):15 WebSocket connection to 'ws://127.0.0.1:8000/ws/chat/lobby/' failed: Error during WebSocket handshake: Unexpected response code: 500
(index):26 Chat socket closed unexpectedly
Here is the whole "pip freeze" list if it he
aioredis==1.1.0
asgiref==2.3.2
astroid==1.6.5
async-timeout==3.0.0
attrs==18.1.0
autobahn==18.6.1
Automat==0.7.0
certifi==2018.4.16
channels==2.1.2
channels-redis==2.2.1
colorama==0.3.9
constantly==15.1.0
daphne==2.2.0
Django==2.0.2
django-cors-headers==2.2.0
djangorestframework==3.8.2
hiredis==0.2.0
hyperlink==18.0.0
idna==2.7
incremental==17.5.0
isort==4.3.4
lazy-object-proxy==1.3.1
mccabe==0.6.1
msgpack==0.5.6
msgpack-python==0.5.6
olefile==0.45.1
Pillow==5.1.0
pylint==1.9.2
pypiwin32==223
pytz==2018.4
pywin32==223
redis==2.10.6
six==1.11.0
Twisted==18.4.0
txaio==2.10.0
wincertstore==0.2
wrapt==1.10.11
zope.interface==4.5.0
Here is the python code: consumer.py
from channels.generic.websocket import AsyncWebsocketConsumer
import json
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = 'chat_%s' % self.room_name
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
self.accept()
async def disconnect(self, close_code):
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
async def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'chat_message',
'message': message
}
)
async def chat_message(self, event):
message = event['message']
await self.send(text_data=json.dumps({
'message': message
}))
routing.py
from django.conf.urls import url
from . import consumers
websocket_urlpatterns = [
url(r'^ws/chat/(?P<room_name>[^/]+)/$', consumers.ChatConsumer)
]
routing.py in mysite
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
import chat.routing
application = ProtocolTypeRouter({
# (http->django views is added by default)
'websocket': AuthMiddlewareStack(
URLRouter(
chat.routing.websocket_urlpatterns
)
),
})
part of settings.py
ASGI_APPLICATION = 'mysite.routing.application'
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 8000)],
},
},
}
Javascript code
var roomName = {{ room_name_json }};
var chatSocket = new WebSocket(
'ws://' + window.location.host +
'/ws/chat/' + roomName + '/');
chatSocket.onmessage = function(e) {
var data = JSON.parse(e.data);
var message = data['message'];
document.querySelector('#chat-log').value += (message + '\n');
};
chatSocket.onclose = function(e) {
console.error('Chat socket closed unexpectedly');
};
document.querySelector('#chat-message-input').focus();
document.querySelector('#chat-message-input').onkeyup = function(e) {
if (e.keyCode === 13) { // enter, return
document.querySelector('#chat-message-submit').click();
}
};
document.querySelector('#chat-message-submit').onclick = function(e) {
var messageInputDom = document.querySelector('#chat-message-input');
var message = messageInputDom.value;
chatSocket.send(JSON.stringify({
'message': message
}));
messageInputDom.value = '';
};
Thanks for the help
In my case I used Nginx to forward the Redis request, which caused a problem in the protocol to access Redis. Therefore, I shut down the forwarding of Nginx and used rinetd to forward this request, so as to check whether the last communication protocol between your application and Redis is correct
Is there any chance you did not have a redis server running on your machine when running your django server? On a mac I did brew install redis
and then redis-server
and then ran my django server on another terminal window and all worked fine.
To connect to the server with TSL certificate you need to tell redis that this certificate exists in the way of the connection. This should work for all proxy like nginx and traefik.
redis-cli -u redis://redis.example.com:6379 --tls
then depending on the certificate type and if the certificate is in your store you might need to authenticate your client to verify the certificate for you during the connection.
The easiest way to do this is to provide --sni {DNS ADDRESS}
parameter, or to be safe you can pass the whole certificate via --cert
or --cacert
depending on your configuration
Full connection string
redis-cli -u redis://redis.example.com:6379 --tls --sni redis.example.com
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With