Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protocol error, got "H" as reply type byte

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

like image 607
ranjith Avatar asked Jun 20 '18 14:06

ranjith


3 Answers

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

like image 198
gt_xiong Avatar answered Nov 08 '22 22:11

gt_xiong


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.

like image 3
chemeng Avatar answered Nov 08 '22 22:11

chemeng


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
like image 1
Tomasz Juszczak Avatar answered Nov 08 '22 23:11

Tomasz Juszczak