পাউন্ড: WebSocket হ্যান্ডেল কনফিগার


3

এটা কনফিগার করা সম্ভব পাউন্ড WebSocket অনুরোধ হ্যান্ডেল করতে? যদি না হয়, একটি বিপরীত প্রক্সি জন্য সর্বোত্তম বিকল্প কি? আমি পাউন্ড বা সমান হালকা ওজন বিপরীত প্রক্সি ব্যবহার করতে চাই।


এটা ইতিমধ্যে websockets সমর্থন করে না? Websockets স্বাভাবিক HTTP যোগাযোগ অনুকরণ যাতে বিদ্যমান প্রক্সি তাদের পরিচালনা করতে পারেন।
John Dvorak

@JanDvorak - পাউন্ড সমর্থন থাকতে পারে, কিন্তু এটি কাজ বলে মনে হচ্ছে না। আমার পরীক্ষায় (যা প্রক্সির উভয় পাশে টিসিপিডাম ক্যাপচারগুলিকে অন্তর্ভুক্ত করেছিল), এটি প্রদর্শিত হয়েছিল যে পাউন্ডটি প্রোটোকল আপগ্রেড করার অনুমতি দেয়, ক্লায়েন্টকে পেলোডের প্রথম কয়েকটি বাইট প্রেরণ করে, তারপর কেবল ট্রান্সমিটিং বন্ধ করে দেয়। আমি এটা কাজ করে না যে নির্ধারণ অতিক্রম অতিক্রম পরীক্ষা না। আমি একটি সমাধান প্রয়োজন, পাউন্ড এর সোর্স কোড মাধ্যমে একটি romp না। :-P
ghoti

উত্তর:


1

পাউন্ড প্রোটোকল আপগ্রেড সমর্থন করে এমন কোডটি অন্তর্ভুক্ত করে বলে মনে হচ্ছে, তবে আমি এটি কাজ করতে সক্ষম হব না। না ফোরাম এবং পাউন্ড মেইলিং তালিকায় বিভিন্ন লোকেরা আছে।

একটি সুন্দর বিস্তারিত পোস্ট আছে exratione.com যা SSL এর পিছনে লোড ভারসাম্য ওয়েবসকেটগুলির জন্য অনেকগুলি বিকল্প বর্ণনা করে, যার মধ্যে পাউন্ড অন্তর্ভুক্ত রয়েছে (যা লেখক অবশেষে ছেড়ে দিয়েছিলেন)। এই পোস্টের সমাপ্তি (২01২ সালের প্রথম দিক থেকে তারিখগুলি) কোনও নেই ভাল সমাধান।

যে পোস্ট থেকে, nginx websocket প্রক্সি সমর্থন যোগ করা হতে পারে , তাই যে মূল্য খুঁজছেন। nginx কনফিগারেশনের ক্ষেত্রে আরও কিছু জড়িত, এবং আইআইআরসি স্টিকি সেশন ম্যানেজমেন্ট সম্পর্কিত কিছু সীমাবদ্ধতা রয়েছে, কিন্তু এটি একটি নির্ভরযোগ্য, দ্রুত বিপরীত প্রক্সি যা SSL সমর্থন করে।

আপনার যদি আপনার ওয়েবসকেট সংযোগগুলির জন্য SSL প্রয়োজন না হয় তবে আপনি একটি সহজ টিসিপি লোড ব্যালান্সারটি চেষ্টা করতে পারেন। থেকে চয়ন করতে অনেক আছে - HAProxy লিনাক্স লোকেরা ভালোবাসে, কিন্তু সহজ, উচ্চমানের বিকল্পগুলি বিদ্যমান কলম , ওপেনBSডি এর relayd (অথবা তার FreeBSD পোর্ট ), ইত্যাদি

যদি আপনি শুধুমাত্র একটি ব্যাক-এন্ড সার্ভারের সামনে একটি বিপরীত প্রক্সি প্রয়োজন এবং ব্যালেন্স লোড করার প্রয়োজন হয় না তবে আপনি সম্ভবত সামনের সারির HTTPS / WSS সংযোগগুলি পেতে এবং স্ট্রিংটি অভ্যন্তরীণ ব্যাক-এর সাথে সংযোগ করতে ব্যবহার করতে পারেন। এখানে কিছু নমুনা স্টোনেল কনফিগারেশন । অন্যথায়, আপনি সামনে স্টোনেল ব্যবহার করতে সক্ষম হতে পারে কলম , কিন্তু আপনি পরীক্ষা করতে হবে - আমি এটা সম্পন্ন না করেছি, এবং এটি কাজ করবে কিনা তা আপনাকে বলতে পারে না। (যদি আপনি চেষ্টা করেন, দয়া করে আমাদের আপনার ফলাফল জানতে দিন!)

হালনাগাদ:

HAProxy 1.5.0 19 শে জুন, ২014 এ প্রকাশিত হয়েছিল। এই সংস্করণটি সংযোগের উভয় পাশে নেটিভ SSL সমর্থন অন্তর্ভুক্ত, যার অর্থ এখন এটি একটি ওয়েবসকেট প্রক্সির জন্য আমার "পছন্দের" সমাধান। কনফিগারেশন অবিশ্বাস্যভাবে সহজ:

frontend http-in
    ...
    bind 192.0.2.1:80     # if you want
    bind 192.0.2.1:443 ssl crt /etc/ssl/yadda.pem
    use_backend ws if { hdr(Upgrade) -i WebSocket }

backend ws
    server node1 192.168.1.111:8000
    server node2 192.168.1.112:8000

অথবা অন্যথায়, আপনি একটি ACL ব্যবহার করে হোস্টনাম দিয়ে এটি করতে পারেন:

frontend http-in
    ...
    acl is_ws hdr_end(host) -i ws.example.com
    use_backend ws if is_ws

1

@ ঘটি এর উত্তর ভাল কাজ করেছে এবং সম্ভবত আমি প্রস্তাবিত স্টানার ব্যবহার করতে থাকব কিন্তু এই সমস্যাটি আমাকে জঘন্য করেছে, তাই আমি @ জেনডোরাকের মতামত প্রসারিত করব, যিনি আরও বিস্তারিতভাবে না গিয়ে কিছু পরীক্ষা করেছেন বলে দাবি করেছেন।

আমি নিম্নলিখিত সহজ পাইথন websocket সার্ভার ব্যবহার করা হয় যা থেকে প্রাপ্ত https://gist.github.com/jkp/3136208

import struct
import SocketServer
from base64 import b64encode
from hashlib import sha1
from mimetools import Message
from StringIO import StringIO

class WebSocketsHandler(SocketServer.StreamRequestHandler):
    magic = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'

    def setup(self):
        SocketServer.StreamRequestHandler.setup(self)
        print "connection established", self.client_address

    def handle(self):
        data = self.request.recv(1024).strip()
        headers = Message(StringIO(data.split('\r\n', 1)[1]))
        if headers.get("Upgrade", None) != "websocket":
            return
        print 'Handshaking...'
        key = headers['Sec-WebSocket-Key']
        digest = b64encode(sha1(key + self.magic).hexdigest().decode('hex'))
        response = 'HTTP/1.1 101 Switching Protocols\r\n'
        response += 'Upgrade: websocket\r\n'
        response += 'Connection: Upgrade\r\n'
        response += 'Sec-WebSocket-Accept: %s\r\n\r\n' % digest
        self.request.send(response)

        length = ord(self.rfile.read(2)[1]) & 127
        if length == 126:
            length = struct.unpack(">H", self.rfile.read(2))[0]
        elif length == 127:
            length = struct.unpack(">Q", self.rfile.read(8))[0]
        masks = [ord(byte) for byte in self.rfile.read(4)]
        decoded = ""
        for char in self.rfile.read(length):
            decoded += chr(ord(char) ^ masks[len(decoded) % 4])

        print decoded

        self.request.send(chr(129))
        length = len(decoded)
        if length <= 125:
            self.request.send(chr(length))
        elif length >= 126 and length <= 65535:
            self.request.send(126)
            self.request.send(struct.pack(">H", length))
        else:
            self.request.send(127)
            self.request.send(struct.pack(">Q", length))
        self.request.send(decoded)

        self.finish()

if __name__ == "__main__":
    server = SocketServer.TCPServer(
        ("localhost", 9000), WebSocketsHandler)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        print "Got ^C"
        server.server_close();
        print "bye!"

এবং আমি নিম্নলিখিত এইচটিএমএল সঙ্গে এটি মিলিত যা থেকে ধার করা হয় http://www.websocket.org/echo.html

<!DOCTYPE html>
<meta charset="utf-8" />
<title>WebSocket Test</title>
<script language="javascript" type="text/javascript">
  var wsUri = "ws://localhost:9000/";
  var output;
  function init() {
    output = document.getElementById("output");
    testWebSocket();
  }
  function testWebSocket() {
    websocket = new WebSocket(wsUri);
    websocket.onopen = function(evt) { onOpen(evt) };
    websocket.onclose = function(evt) { onClose(evt) };
    websocket.onmessage = function(evt) { onMessage(evt) };
    websocket.onerror = function(evt) { onError(evt) };
  }
  function onOpen(evt) {
    writeToScreen("CONNECTED");
    doSend("WebSocket rocks");
  }
  function onClose(evt) {
    writeToScreen("DISCONNECTED");
  }
  function onMessage(evt) {
    writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
    websocket.close();
  }
  function onError(evt) {
    writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
  }
  function doSend(message) {
    writeToScreen("SENT: " + message); 
    websocket.send(message);
  }
  function writeToScreen(message) {
    var pre = document.createElement("p");
    pre.style.wordWrap = "break-word";
    pre.innerHTML = message;
    output.appendChild(pre);
  }
  window.addEventListener("load", init, false);
</script>
<h2>WebSocket Test</h2>
<div id="output"></div>
</html>

এটি ভাল কাজ করেছে, তাই আমি নিম্নোক্ত কনফিগারেশন এন্ট্রি দিয়ে মাঝখানে পাউন্ড রাখি:

ListenHTTP
    Address 127.0.0.1
    Port    9999
    Service
            BackEnd
                    Address 127.0.0.1
                    Port    9000
            End
    End
End

এবং 9000 থেকে 9999 পর্যন্ত এইচটিএমএল পোর্ট পরিবর্তন করে। সেই পরিবর্তনের পরে এটি কাজ বন্ধ করে দেয়।

Wireshark সঙ্গে ট্রাফিক বিশ্লেষণ, আমি খুঁজে পাওয়া যায় যে HTTP 101 অনুরোধ প্রোটোকল সুইচ সঠিকভাবে ফেরত পায়। কিন্তু পরবর্তী প্রথম ওয়েবককেট প্যাকেট পাউন্ড দ্বারা অগ্রসর হয় না। এই দ্বারা নিশ্চিত করা হয় print পাইথন সার্ভার স্ক্রিপ্ট আউটপুট যা প্রাপ্ত না WebSocket rocks মাঝখানে পাউন্ড সঙ্গে বার্তা।

যখনই পাউন্ড একটি ওয়েবসকেট বার্তা পায়, তখন এটি বার্তা বন্ধ করে এবং পরিবর্তে লিখতে পারে e414 headers: request URI too long syslog করতে। পাউন্ড সোর্স কোডটি দেখে মনে হচ্ছে পাউন্ড HTTP শিরোলেখগুলি বিশ্লেষণ করার চেষ্টা করে। এটি করার জন্য প্রথমে এটি একটি ইওএল অনুসন্ধান করে যা এটি ওয়েবসকেট বার্তাটিতে খুঁজে পাওয়া যায় না এবং এইভাবে বার্তাটিকে অবৈধ বলে মনে করে।

সুতরাং মনে হচ্ছে OP এর প্রশ্নের উত্তরটি আসলেই হল: পাউন্ড ওয়েবসকেটটি করতে পারে না।

আমি এই সমস্যা সম্পর্কে পাউন্ড তালিকাতে একটি ইমেল লিখেছি: http://www.apsis.ch/pound/pound_list/archive/2014/2014-01/1388844924000


সুন্দরভাবে সম্পন্ন. এই আপডেটের জন্য ধন্যবাদ। :-)
ghoti
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.