Как написать неблокирующий сервер? - PullRequest
0 голосов
/ 08 июня 2018

После многих трудностей, связанных с работой ros и http-сервера на базе Python, у меня возникла другая проблема - объединить два разных кода.

Вот что я написал до сих пор, чтобы написать кодкоторые публикуют ros темы, но в то же время отвечают на http-сервер.Проблема в том, что с сервером все в порядке, если я не заменю

httpd.serve_forever()

на

httpd.service_actions

, чтобы сделать его неблокирующим.Тогда сервер не отвечает.Есть ли способ решить эту проблему, но при этом оставить код без блочности?

#!/usr/bin/env python3

import rospy
from std_msgs.msg import String

from http.server import BaseHTTPRequestHandler, HTTPServer

class S(BaseHTTPRequestHandler):
    def _set_headers(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()

    def do_GET(self):
        self._set_headers()
        self.wfile.write(b"<html><body><h1>hi!</h1></body></html>")

    def do_HEAD(self):
        self._set_headers()

    def do_POST(self):
        # Doesn't do anything with posted data
        self._set_headers()
        self.wfile.write(b"<html><body><h1>POST!</h1></body></html>")

def http_server_init(port,server_class=HTTPServer, handler_class=S):
    server_address = ('', port)
    httpd = server_class(server_address, handler_class)
    print('Starting httpd...')
    return (httpd)

def http_server_loop(httpd):
    #httpd.serve_forever()
    httpd.service_actions()

def talker_init():
    pub = rospy.Publisher('chatter', String, queue_size=10)
    rospy.init_node('talker', anonymous=True)
    rate = rospy.Rate(10) # 10hz
    return (pub,rospy,rate)

def talker_loop(pub,rospy,rate):
        hello_str = "hello world %s" % rospy.get_time()
        rospy.loginfo(hello_str)
        pub.publish(hello_str)
        rate.sleep()

if __name__ == '__main__':
    from sys import argv
    if len(argv) == 2:
        http_port=int(argv[1])
    else:
        http_port=8080
    httpd=http_server_init(http_port)
    try:
        pub,rospy,rate=talker_init()
        while not rospy.is_shutdown():
            http_server_loop(httpd)
            talker_loop(pub,rospy,rate)
    except rospy.ROSInterruptException:
        pass

Кстати, в ROS этот код должен вызываться через

rosrun <packagename> <script>.py

Вызов изbash приводит к ошибке.Если вы не удалите коды, связанные с ROS.

...