Failed error during websocket handshake unexpected response code 500

Introduction Where to Start mysql installation Install Nginx Install php virtual environment Redis Installation and Configuration Redis installation Configure redis to use unix domain sockets Configure Redis as the back end of django session storage and caching django-websocket-redis install TUTF-8...
  • Introduction
  • Where to Start

    • mysql installation
    • Install Nginx
    • Install php
    • virtual environment
  • Redis Installation and Configuration

    • Redis installation
    • Configure redis to use unix domain sockets
  • Configure Redis as the back end of django session storage and caching
  • django-websocket-redis

    • install
    • To configure

      • development environment
      • production environment
    • Use

      • Part django
      • Part js
    • deploy

      • Uwsgi
      • Nginx
  • Summary of Common Commands
  • Common mistakes

    • Updates on Web Pages
    • Repeated display of chat messages
    • About safari
    • About 502
    • About 500
  • Requirestxt attached
  • Reference summary

Introduction

Because the project needs to include chat function, we hope to use websocket to communicate. However, dwebsocket module can not work properly under Nginx+Uwsgi deployment although it runs normally on runserver. In fact, due to the workflow of the wsgi protocol, long connections such as WebSockets are almost impossible to maintain. So we need to find a new way to realize it. Following is a description of the development environment and production environment configuration for using Redis as a django cache and websocket.

Note: Because I use root account, sudo is not required. If there is insufficient permission in the installation, Please add sudo yourself.

Write this type of blog for the first time. If there are any mistakes, please correct them.

Where to Start

The original configuration is basically in accordance with Huang Chao’s blog The content of this paragraph is basically consistent with this article, intercepting the content of installing virtual environment. If you have already configured Uwsgi and Nginx, just need support for websocket, you can skip this section.

mysql installation

apt install mariadb-server mariadb-client libmariadbd-dev libmysqlclient-dev
service mysql restart
service mysql status
mysql_secure_installation
Enter current password for root:[Just enter]
Set root password?[Y/n] Y


Remove anonymous users?[Y/n] Y
Disallow root login remotely?[Y/n] Y
Remove test database and access to it? [Y/n] Y
Reload privilege tables now?[Y/n] Y



service mysql restart

Install Nginx

If you run server locally, you do not need to install Nginx.

apt install nginx

Install php

apt install php php-fpm

virtual environment

apt install python3-dev
apt install python3-venv
python3 -m venv /path/to/.venv

Enter the virtual environment:

source /path/to/.venv/bin/activate

Withdrawal from the virtual environment:

deactivate

Note: Please pay attention to replacing / path/to with your own path.

Redis Installation and Configuration

Original link

Redis installation

apt-get install redis-server

After installation, use under linux:

service redis-server start

Open redis-server.

This command can be used to detect whether redis-server is working properly:

redis-cli ping
PONG

Receive PONG instructions for normal operation.

Configure redis to use unix domain sockets

This small segment setting allows redis to use unix domain sockets instead of TCP/IP. You can choose to ignore this paragraph. This results in slightly different settings in the settings.py file of django.

vim /etc/redis/redis.conf
# Accept connections on the specified port, default is 6379.
# If port 0 is specified Redis will not listen on a TCP socket.
# port 6379

# If you want you can bind a single interface, if the bind option is not
# specified all the interfaces will listen for incoming connections.
#
# bind 127.0.0.1

# Specify the path for the unix socket that will be used to listen for
# incoming connections. There is no default, so Redis will not listen
# on a unix socket when not specified.
#
unixsocket /path/to/redis.sock
unixsocketperm 777

In fact, the above will be:

port 6379
bind 127.0.0.1

Comment it out and add:

unixsocket /path/to/redis.sock
unixsocketperm 777

Cancel the comment.
After changing conf, use:

service redis-server restart

Restart the service.

Configure Redis as the back end of django session storage and caching

In the settings.py file, set:

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "unix:///path/to/redis.sock?db=0",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}

Guarantee the following in MIDDLEWARE_CLASSES:

MIDDLEWARE_CLASSES = [
    'django.middleware.cache.UpdateCacheMiddleware',    
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    ...,
    'django.middleware.cache.FetchFromCacheMiddleware', 
    ]

So far, cache can be used in code. The simplest example:

from django.core.cache import cache
example_key = "IAmKey"
example_value = cache.get(example_key)
cache.set(example_key, {"value1", 1})
cache.set("anotherKey", "hello", timeout=None)

redis is a key-value storage mechanism. The cache.get(key) function returns None when the value corresponding to the key does not exist. The cache.set(key, value) function can store data, and the optional parameter timeout determines the expiration time in seconds. Timout = 0 means immediate failure and timeout=None means never failure.

All data stored in redis can be deleted most directly:

redis-cli flushall

In addition, redis can be set to store django session data:

SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"

Note: In the development environment, if the default configuration is not changed when configuring redis, then in settings.py, CACHES sets «LOCATION»=»redis://127.0.0.1:6379/0», where the last 0 represents the database id and can be changed.

django-websocket-redis

First link Official documents In which github Find a routine.
django-websocket-redis needs to configure Redis, use Redis as a message queue, and maintain connections.

install

Install using pip:

pip install django-websocket-redis

To configure

The configuration of the development environment (runserver) is different from that of the production environment (Nginx+Uwsgi). Just take this as an example:

development environment

In the development environment, redis uses the default configuration, i.e. 127.0.0.1:6379. The redis-related settings configuration is shown in the previous note.

In settings.py

INSTALLED_APPS = [
    ...
    'ws4redis',
    ...
]
TEMPLATES = [
    {
        ...,
        'OPTIONS': {
            'context_processors': [
                ...,
                'django.template.context_processors.static',
                'django.contrib.auth.context_processors.auth',
                'ws4redis.context_processors.default',
            ],
            ...,
        },
    },
]
WSGI_APPLICATION = 'ws4redis.django_runserver.application'
WS4REDIS_CONNECTION = {
    'db': 7
}
WS4REDIS_EXPIRE = 3600
WEBSOCKET_URL = '/ws/'
WS4REDIS_PREFIX = 'ws'

production environment

In production environments, redis uses unix domain socket configuration, as described earlier

In settings.py

INSTALLED_APPS = [
    ...
    'ws4redis',
    ...
]
TEMPLATES = [
    {
        ...,
        'OPTIONS': {
            'context_processors': [
                ...,
                'django.template.context_processors.static',
                'django.contrib.auth.context_processors.auth',
                'ws4redis.context_processors.default',
            ],
            ...,
        },
    },
]
WSGI_APPLICATION = 'appname.wsgi.application'
WS4REDIS_CONNECTION = {
    'unix_socket_path': '/path/to/redis.sock',
    'db': 5
}
WS4REDIS_EXPIRE = 3600
WEBSOCKET_URL = '/ws/'
WS4REDIS_PREFIX = 'ws'

Here the appname is changed to the name of the project.

* Note: There are many options in WS4REDIS_CONNECTION, just write different from redis default configuration. Note that the’db’item defaults to 0, indicating the selected database, not the same as the one selected in CACHES.

WS4REDIS_EXPIRE represents the message’s expiration time in seconds.

Use

Official documents about the use of written more comprehensive, here only in conjunction with my project to explain some of the functions.

Part django

In my project, I only used to send messages to designated users. ws4redis can also set up broadcasting or send messages to groups.

from ws4redis.publisher import RedisPublisher
from ws4redis.redis_store import RedisMessage

redis_publisher = RedisPublisher(facility='foobar', users=['username1', 'username2'])
message = RedisMessage('Hello World')

redis_publisher.publish_message(message)

Here username 1, username 2 is actually:

from django.contrib.auth.models import User

In User.username, RedisPublisher sends messages to websocket connections logged in with these usernames.

Part js

The js section can be written in the same way as WebSocket:

var websocket = new WebSocket("ws://yourhost/ws/foobar?subscribe-user")
websocket.on.onmessage = function (data) {
    ......
}

Replace yourhost with the target address. / ws / is the WEBSOCKET_URL previously specified in settings.py, and foobar?subscribe-user is a parameter that determines which messages this connection accepts. This setting corresponds to the previous django code for receiving messages to that user. Other settings can be found in official documents.

Note: In my project, ws4redis is only used to send messages from server to client, and the messages from client to server are sent by POST request.
In fact, I haven’t found a way to handle messages sent from client to server. These messages are received and stored by redis, waiting for django to get them. But there’s no (more likely I didn’t find) way to alert django when the message arrives at redis, instead django gets the message itself when it needs it.
The & echo parameter was mentioned in the official document, but I didn’t find its effect.

deploy

The project deployment with django-websocket-redis configuration is different from the simple Django project. The project is deployed according to the production environment mentioned above. Installation of Nginx et al. has been mentioned before.

Note: This deployment method is deployed in Ubuntu 16.04. Again, I used root account. If there is insufficient authority, Please add sudo.

Because there are many paths involved, in order to look more intuitive, the project is assumed to be named example.

Uwsgi

First, make sure that openssl is installed:

apt-get install openssl

Install Uwsgi:

pip install uwsgi

If you haven’t installed django in your virtual environment, you can:

pip install Django
pip install django

However, django seems to have recently updated version 2.0, which may cause your project to fail to work properly, so you can use:

pip install Django==1.11.7

Explicit version. requirements.txt for my project will be given at the end of this article.

Next, you need to set up uwsgi configuration for django and websocket respectively:

django

Create py files

vim /path/to/example/example/wsgi_django.py
import os
os.environ.update(DJANGO_SETTINGS_MODULE='example.settings')
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

Create ini file

vim /path/to/uwsgi_django.ini
[uwsgi]
socket = /path/to/django.sock
chdir = /path/to/example
wsgi-file = example/wsgi_django.py
touch-reload = /path/to/reload_django
home = /path/to/.venv/
processes = 5
chmod-socket = 777
buffer-size = 32768
master = true
daemonize = /path/to/django.log
vacuum = true 

websocket

Create py files

vim /path/to/example/example/wsgi_websocket.py
import os
import gevent.socket
import redis.connection
redis.connection.socket = gevent.socket
os.environ.update(DJANGO_SETTINGS_MODULE='example.settings')
from ws4redis.uwsgi_runserver import uWSGIWebsocketServer
application = uWSGIWebsocketServer()

Create ini file

vim /path/to/uwsgi_websocket.ini
[uwsgi]
http-socket = /path/to/websocket.sock
chdir = /path/to/example
wsgi-file = example/wsgi_websocket.py
touch-reload = /path/to/reload_websocket
home = /path/to/.venv/
processes = 2
gevent = 1000
buffer-size = 32768
chmod-socket = 777
http-websockets = true
master = true
daemonize = /path/to/websocket.log
vacuum = true

Here the touch-reload file needs to be created manually, and other files will be created automatically at run time.

Run separately:

uwsgi --ini /path/to/uwsgi_django.ini
uwsgi --ini /path/to/uwsgi_websocket.ini

When there is a file change, execute:

touch /path/to/reload_django
touch /path/to/reload_websocket

uwsgi can be restarted separately.

Nginx

Change user:

vim /etc/nginx/nginx.conf

Change the first line of www-data to your user name (mine is root).

Fill in the configuration:

sudo vim /etc/nginx/conf.d/somename.conf
server {
 listen 80;
 server_name ***.***.***.***; 
 charset utf-8;

client_max_body_size 75M;


location /static {
 alias /path/to/example/static;
 }


location / {
 uwsgi_pass unix:///path/to/django.sock;
 include /etc/nginx/uwsgi_params;
 }
location /ws/ {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_pass http://unix:/path/to/websocket.sock;

 }
}

Restart Nginx:

service nginx restart

So far, the deployment has been completed.

Summary of Common Commands

After the project changes, use:

touch /path/to/reload_django
touch /path/to/reload_websocket

Restart uwsgi.

By:

redis-cli command

Operate redis, such as:

redis-cli flushall

You can empty the redis database.

If necessary, adopt:

service nginx restart

Restart the nginx server.

Pass:

service redis-server restart

Restart redis server.

Pass:

ps aux|grep uwsgi
ps aux|grep redis-server
ps aux|grep nginx

You can view the service process separately and pass:

Or:

killall -9 uwsgi
killall -9 redis-server
killall -9 nginx

Forced interruption.

After deployment according to this method, / ws / requests, common requests and related error information are recorded in / path/to/django.log and / path/to/websocket.log respectively, which can be viewed.

Common mistakes

Updates on Web Pages

After configuring redis, it may occur that there is no update information after a page is refreshed. Looking at the log, it is found that no corresponding http request has been received. This (possibly) is due to the caching mechanism of redis. By adding in settings.py:

CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True
CACHE_MIDDLEWARE_SECONDS = 0

To solve this problem. The first means that only anonymous users are cached, and the second means that the cache invalidation time is set to immediately invalidate. I found that adding the first item didn’t solve my problem, so I added the second one. Maybe there’s a more elegant way to solve it, but I didn’t find it.

Repeated display of chat messages

After configuring ws4redis in my project, when a chats with b, a goes offline, refreshes the page and logs in again, the last message from B to a will be received again. The check found that it was websocket that received the message again.

The solution is to change WS4REDIS_EXPIRE = 0 in settings.py to invalidate the message in redis immediately after it is received by the front end.

About safari

ws4redis actually works well in safari. But when using runserver, it may appear at the back end:

websocket.receive: WebSocketError Unexpected EOF while decoding header

At the front end:

WebSocket connection to 'ws://127.0.0.1:8000/ws/foobar?subscribe-user' failed: Invalid HTTP version string: HTTP/1.0

This issue was raised as an issue in github, but it has not changed. The result of the discussion is the problem of django runserver. This problem disappeared after deployment to the server.

About 502

If 502 Bad Gateway occurs when a websocket connection is established, it is likely that the Nginx configuration is incorrectly set. Check that the conf file of Nginx is correct in forwarding the request to Uwsgi.

About 500

If a websocket connection is established:

WebSocket connection to 'ws://***' failed: Error during WebSocket handshake: Unexpected response code: 500

See in the log:

you need to build uWSGI with SSL support to use the websocket handshake api function !!!

Explain that your uwsgi does not support ssl.

This is a very troublesome problem because the server was already installed with openssl when this error occurred. The simple solution is to install Uwsgi outside the virtual environment after installing openssl and execute:

killall -9 uwsgi
uwsgi --ini /path/to/uwsgi_django.ini
uwsgi --ini /path/to/uwsgi_websocket.ini

In general, this solves the problem, because the Uwsgi installed in the virtual environment may not be able to locate your openssl.

If you still can’t solve this problem, A Problem on Stack Overflow More possible solutions are given.

Attachment: requirements.txt

Following is the requirements.txt of my project so far, which is not guaranteed to be all useful, but if you find any packages missing somewhere in the process of configuring according to this article, maybe you can find them here:

amqp==2.2.2
billiard==3.5.0.3
celery==4.1.0
coverage==4.4.2
Django==1.11.7
django-redis==4.8.0
django-redis-cache==1.7.1
django-redis-sessions==0.6.1
django-websocket-redis==0.5.1
flake8==3.5.0
gevent==1.2.2
greenlet==0.4.12
kombu==4.1.0
mccabe==0.6.1
mysqlclient==1.3.12
pep8-naming==0.4.1
pycodestyle==2.3.1
pycrypto==2.6.1
pyflakes==1.6.0
python-redis-lock==3.2.0
pytz==2017.3
redis==2.10.6
redis-cache==0.1.3
redis-structures==0.1.6
six==1.11.0
vine==1.1.4
vital-tools==0.1.8
wsaccel==0.6.2

Reference summary

1.Using Redis as Django’s session store and cache backend

2.Websockets for Django applications using Redis as message queue

3.How to Set Up My First Server?

4.Error during WebSocket handshake: Unexpected response code: 500

Есть проект с JSF, primefaces и atmosphere. После старта новой сессии примерно через 30 секунд вылетает ошибка:

WebSocket connection to 'ws://localhost:8080/project/primepush/ticker?X-Atmosphere-tracking-id=0&X-Atmosphere-Framework=2.2.9-javascript&X-Atmosphere-Transport=websocket&X-Atmosphere-TrackMessageSize=true&X-atmo-protocol=true' failed: Error during WebSocket handshake: Unexpected response code: 500
        Websocket closed, reason: Connection was closed abnormally (that is, with no close frame being sent).
        Websocket failed. Downgrading to Comet and resending

Стэктрейс:

java.io.IOException: java.util.concurrent.TimeoutException
    at org.glassfish.grizzly.nio.transport.TCPNIOTransportFilter.handleRead(TCPNIOTransportFilter.java:90)
    at org.glassfish.grizzly.filterchain.TransportFilter.handleRead(TransportFilter.java:173)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.read(DefaultFilterChain.java:351)
    at org.glassfish.grizzly.filterchain.FilterChainContext.read(FilterChainContext.java:736)
    at org.glassfish.grizzly.http.io.InputBuffer.blockingRead(InputBuffer.java:1107)
    at org.glassfish.grizzly.http.server.io.ServerInputBuffer.blockingRead(ServerInputBuffer.java:95)
    at org.glassfish.grizzly.http.io.InputBuffer.fill(InputBuffer.java:1131)
    at org.glassfish.grizzly.http.io.InputBuffer.read(InputBuffer.java:348)
    at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:267)
    at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:270)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.read1(BufferedReader.java:210)
    at java.io.BufferedReader.read(BufferedReader.java:286)
    at java.io.Reader.read(Reader.java:140)
    at org.atmosphere.util.IOUtils.readEntirelyAsString(IOUtils.java:165)
    at org.atmosphere.util.IOUtils.readEntirely(IOUtils.java:116)
    at org.primefaces.push.impl.PushEndpointHandlerProxy.onRequest(PushEndpointHandlerProxy.java:151)
    at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:206)
    at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:108)
    at org.atmosphere.container.GlassFishServ30WebSocketSupport.service(GlassFishServ30WebSocketSupport.java:60)
    at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:2241)
    at org.atmosphere.cpr.AtmosphereServlet.doPost(AtmosphereServlet.java:190)
    at org.atmosphere.cpr.AtmosphereServlet.doGet(AtmosphereServlet.java:176)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.glassfish.tyrus.servlet.TyrusServletFilter.doFilter(TyrusServletFilter.java:260)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.util.concurrent.TimeoutException
    at org.glassfish.grizzly.nio.tmpselectors.TemporarySelectorReader.read(TemporarySelectorReader.java:126)
    at org.glassfish.grizzly.nio.tmpselectors.TemporarySelectorReader.read(TemporarySelectorReader.java:75)
    at org.glassfish.grizzly.AbstractReader.read(AbstractReader.java:72)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransportFilter.handleRead(TCPNIOTransportFilter.java:77)
    ... 63 more

web.xml

<context-param>
    <param-name>com.sun.faces.enableRestoreView11Compatibility</param-name>
    <param-value>true</param-value>
</context-param>
<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
</context-param>
<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet>
    <servlet-name>Push Servlet</servlet-name>
    <servlet-class>org.primefaces.push.PushServlet</servlet-class>
    <async-supported>true</async-supported>
</servlet>
<servlet-mapping>
    <servlet-name>Push Servlet</servlet-name>
    <url-pattern>/primepush/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<session-config>
    <session-timeout>
        180
    </session-timeout>
</session-config>
<welcome-file-list>
    <welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<context-param>
    <param-name>primefaces.THEME</param-name>
    <param-value>bootstrap</param-value>
</context-param>

Фронт:

        <p:socket channel="/ticker">
            <p:ajax event="message" update="mainLayout"/>
        </p:socket>

Бэк:

@PushEndpoint("/ticker") 
public class Socket {

    @OnMessage(decoders = {JSONDecoder.class}, encoders = {JSONEncoder.class})
    public String onMessage(RemoteEndpoint remoteEndpoint, String str) {
        return str;
    }
}

Апдейт фронта:

public void updateTicker() {
    EventBus eventBus = EventBusFactory.getDefault().eventBus();
    eventBus.publish("/ticker", ticker);
}

Все происходит в ApplicationScoped бине. Исключение вылетает после старта новой сессии, примерно через 10 секунд. Судя по ошибке, атмосфера не может приконнектиться к бэку. Почему такое может происходить и как это исправить? Я пробовал по-разному менять пути, но максимум чего добился — ошибка с 500 изменилась на 404.

i m using angular and i have done the authentification succesully
but when using the websocket i have got erorr .

 WebSocket connection to 'ws://52.232.22.124/api/socket' failed: Error during WebSocket handshake: Unexpected response code: 500

Hello!

I also care. What is the solution? Very disturbing!

Thanks

Hello!

Did you find any solution for this?

Hi!
I have the same problem. Anyone found the solution?

I login with ajax like this:

get login() {
    $.ajax({
      type: 'POST',
      dataType: "json",
      data: {
        "email": "MY_USER",
        "password": "MY_PASSWD"
      },
      url: 'http://MY_URL:8082/api/session/',
      headers: {
          "Authorization": "Basic " + btoa("MY_USER" + ":" + "MY_PASS")
      },
      success: function (response) {
          console.log(response);
          mapTrack.openWebsocket;         
      }
    });

    get openWebsocket() {
      var socket;
      socket = new WebSocket('ws://MY_URL:8082/api/socket');

      socket.onclose = function (event) {
        console.log("WebSocket closed");
      };

      socket.onmessage = function (event) {
        mapTrack.markers(JSON.parse(event.data));
        //console.log(event.data);
      };
    }

The reponse is:

For the session function is:

Object
id: 89
attributes: {notificationTokens: "fQR5J86Wdb8:APA91bH1IwEB0DJuEzv4iQRWJd9tnpJ0HSU55U…VzJiB5Kkkj4f5B3jg1nsH0QW1S2yxy99ApZcYckaS0jsI0QQM"}
name: "prueba"
login: ""
email: "MY_EMAIL"
phone: ""
readonly: false
administrator: false
map: ""
latitude: 0
longitude: 0
zoom: 0
twelveHourFormat: false
coordinateFormat: ""
disabled: false
expirationTime: null
deviceLimit: -1
userLimit: 0
deviceReadonly: false
token: null
limitCommands: false
poiLayer: ""
password: null
__proto__: Object

For the WebSocket function is:

init.js:167 WebSocket connection to 'ws://MY_URL:8082/api/socket' failed: Error during WebSocket handshake: Unexpected response code: 500
get openWebsocket @ init.js:167
init.js:170 WebSocket closed

Hello everyone

Did you find any solution for this?

Any suggestion, I am trying to consume websocket api in ANGULAR

I have been following this tutorial to build a chat application.

I have been facing WebSocket connection to ‘ws://127.0.0.1:8000/ws/lobby/’ failed: Error during WebSocket handshake: Unexpected response code: 500 error. I checked other solutions too but they don’t seem to work.

The console displays the error at (room.html)

            'ws://'
            + window.location.host
            + '/ws/'
            + roomName
            + '/'
            );

in the console.

The following is displayed in the terminal:

HTTP GET /favicon.ico/ 200 [0.01, 127.0.0.1:53842]
HTTP GET /lobby/?username=darsh 200 [0.01, 127.0.0.1:53842]
WebSocket HANDSHAKING /ws/lobby/ [127.0.0.1:53844]
HTTP GET /favicon.ico/ 200 [0.01, 127.0.0.1:53842]
Exception inside application: No route found for path 'ws/lobby/'.
Traceback (most recent call last):
  File "/home/darsh/.local/lib/python3.8/site-packages/channels/staticfiles.py", line 44, in __call__
    return await self.application(scope, receive, send)
  File "/home/darsh/.local/lib/python3.8/site-packages/channels/routing.py", line 71, in __call__
    return await application(scope, receive, send)
  File "/home/darsh/.local/lib/python3.8/site-packages/channels/sessions.py", line 47, in __call__
    return await self.inner(dict(scope, cookies=cookies), receive, send)
  File "/home/darsh/.local/lib/python3.8/site-packages/channels/sessions.py", line 263, in __call__
    return await self.inner(wrapper.scope, receive, wrapper.send)
  File "/home/darsh/.local/lib/python3.8/site-packages/channels/auth.py", line 185, in __call__
    return await super().__call__(scope, receive, send)
  File "/home/darsh/.local/lib/python3.8/site-packages/channels/middleware.py", line 26, in __call__
    return await self.inner(scope, receive, send)
  File "/home/darsh/.local/lib/python3.8/site-packages/channels/routing.py", line 168, in __call__
    raise ValueError("No route found for path %r." % path)
ValueError: No route found for path 'ws/lobby/'.
WebSocket DISCONNECT /ws/lobby/ [127.0.0.1:53844]

I am attaching the codes that I used:

chat/room.html


<html>
  <head>
    <meta charset="utf-8"/>
    <title>Chatty</title>
    <!-- Include Bulma CSS framework -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.2/css/bulma.min.css">
  </head>

  <body>
    <section class="section">
        <div class="container">
          <div class="columns is-multiline">
            <div class="column is-6 is-offset-3 mb-6">
              <section class="hero is-primary">
                <div class="hero-body">
                  <p class="title">Chatty</p>
                  <p class="subtitle">A simple chat built with Django, Channels and Redis</p>
                </div>
              </section>
            </div>
  
            <div class="column is-6 is-offset-3">
                <div class="box">     
                  <div id="chat-messages">
                  </div>
                </div>
  
                <div class="field">
                  <div class="control">
                    <input class="input" type="text" placeholder="Message" id="chat-message-input">
                  </div>
                </div>
  
                <div class="field">
                  <div class="control">
                    <a class="button is-info" id="chat-message-submit">Submit</a>
                  </div>
                </div>
  
                <small class="has-text-grey-light">Your username: {{ username }}</small>
              </div>
            </div>
         </div>
      </section>
      
      {{ room_name|json_script:"json-roomname" }}
      {{ username|json_script:"json-username" }}

      <script>
        const roomName = JSON.parse(document.getElementById('json-roomname').textContent);
        const userName = JSON.parse(document.getElementById('json-username').textContent);

        const chatSocket = new WebSocket(
            'ws://'
            + window.location.host
            + '/ws/'
            + roomName
            + '/'
            );

            chatSocket.onmessage = function(e) {
                const data = JSON.parse(e.data);
              
                if (data.message) {
                  document.querySelector('#chat-messages').innerHTML += ('' + data.username + ': ' + data.message + '');
                } else {
                  alert('The message was empty!')
                }
            };
              
            document.querySelector('#chat-message-input').focus();
            document.querySelector('#chat-message-input').onkeyup = function(e) {
            if (e.keyCode === 13) {
                document.querySelector('#chat-message-submit').click();
            }
            };
              
            document.querySelector('#chat-message-submit').onclick = function(e) {
            const messageInputDom = document.querySelector('#chat-message-input');
            const message = messageInputDom.value;
            
            chatSocket.send(JSON.stringify({
                'message': message,
                'username': userName,
                'room': roomName
            }));
            
            messageInputDom.value = '';
            };

        chatSocket.onclose = function(e) {
        console.error('The socket closed unexpectedly');
        };

      </script>

  </body>
</html>

routing.py

from django.urls import re_path

from . import consumers

websocket_urlpatterns = [
  path('ws/', consumers.ChatConsumer.as_asgi()), # Using asgi
]

consumers.py

from channels.generic.websocket import AsyncWebsocketConsumer # The class we're using
from asgiref.sync import sync_to_async # Implement later

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

        #Join room
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        await self.accept()

    async def disconnect(self, close_code):
        #Leave group
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    async def receive(self, text_data):
        data = json.loads(text_data)
        message = data['message']
        username = data['username']
        room = data['room']

         # Send message to room group
        await self.channel_layer.group_send(
            self.room_group_name,
            {
            'type': 'chat_message',
            'message': message,
            'username': username
            }
        )

    # Receive message from room group
    async def chat_message(self, event):
        message = event['message']
        username = event['username']

        # Send message to WebSocket
        await self.send(text_data=json.dumps({
            'message': message,
            'username': username
        }))

You need your room_name in your routing:

Use re_path

from django.urls import re_path 

websocket_urlpatterns = [
  re_path('ws/(?P<room_name>w+)/', consumers.ChatConsumer.as_asgi()), # Using asgi
]

In your case this was lobby, hence the error.

Back to Top

Понравилась статья? Поделить с друзьями:
  • Failed error during websocket handshake unexpected response code 301
  • Failed error during websocket handshake unexpected response code 200
  • Failed error caused by file vmfs volumes
  • Failed error 0xc004f074 при активации kmsauto
  • Failed error 0xc004f074 kmsauto windows 10