การเชื่อมต่อกับ TCP Socket จากเบราว์เซอร์โดยใช้ javascript


111

ฉันมีแอปพลิเคชั่น vb.net ที่เปิดซ็อกเก็ตและฟังมัน

ฉันต้องการสื่อสารผ่านซ็อกเก็ตนี้ไปยังแอปพลิเคชันนั้นโดยใช้จาวาสคริปต์ที่ทำงานบนเบราว์เซอร์ นั่นคือฉันต้องส่งข้อมูลบางอย่างในซ็อกเก็ตนี้เพื่อให้แอพที่กำลังฟังอยู่บนซ็อกเก็ตนี้สามารถรับข้อมูลนั้นทำบางอย่างโดยใช้การโทรระยะไกลและรับข้อมูลเพิ่มเติมและนำกลับไปที่ซ็อกเก็ตที่จาวาสคริปต์ของฉันต้องการ อ่านและพิมพ์ในเบราว์เซอร์

ฉันได้ลองแล้ว socket.io, websockify แต่ไม่มีการพิสูจน์ว่ามีประโยชน์

ดังนั้นคำถามคือสิ่งที่ฉันพยายามจะเป็นไปได้หรือไม่? มีวิธีใดบ้างที่จาวาสคริปต์ที่ทำงานในเบราว์เซอร์สามารถเชื่อมต่อกับซ็อกเก็ต tcp และส่งข้อมูลบางส่วนและฟังมันเพื่อตอบสนองข้อมูลเพิ่มเติมบนซ็อกเก็ตและพิมพ์ไปยังเบราว์เซอร์

หากสิ่งนี้เป็นไปได้จะช่วยชี้ทิศทางที่ถูกต้องให้ฉันได้บ้างว่าจะช่วยให้ฉันตั้งเป้าหมายได้อย่างไร


3
ไม่คุณถูก จำกัด ไว้ที่ WebSockets
Bergi

2
@Bergi - HTTP เป็นโปรโตคอลบน tcp เหตุใดจึงสามารถสร้างการเชื่อมต่อ HTTP แต่ไม่สามารถเชื่อมต่อ TCP ได้
AlikElzin-kilaka

@kilaka: เนื่องจาก (มาตรฐาน) APIs ที่มีอยู่ในสภาพแวดล้อมที่เบราว์เซอร์จะถูก จำกัด ให้ผู้ที่
Bergi

อาจซ้ำกันได้: stackoverflow.com/questions/9154035/…
AlikElzin-kilaka

6
ฉันเห็นมาตรฐานใหม่คืบคลานขึ้นกระดูกสันหลังของ Javascript: w3.org/TR/raw-sockets
AlikElzin-kilaka

คำตอบ:


57

สำหรับปัญหาของคุณตอนนี้คุณจะต้องขึ้นอยู่กับ XHR หรือ websockets สำหรับสิ่งนี้

ขณะนี้ยังไม่มีเบราว์เซอร์ยอดนิยมใด ๆ ที่ใช้ API ของซ็อกเก็ตดิบสำหรับจาวาสคริปต์ที่ให้คุณสร้างและเข้าถึงซ็อกเก็ตดิบได้ แต่แบบร่างสำหรับการใช้งาน API ซ็อกเก็ตดิบใน JavaScript อยู่ระหว่างดำเนินการ ดูลิงค์เหล่านี้:
http://www.w3.org/TR/raw-sockets/
https://developer.mozilla.org/en-US/docs/Web/API/TCPSocket

ตอนนี้ Chrome รองรับซ็อกเก็ต TCP และ UDP แบบดิบใน API แบบ 'ทดลอง' แล้ว คุณลักษณะเหล่านี้ใช้ได้เฉพาะกับส่วนขยายและแม้ว่าจะมีการบันทึกไว้ แต่จะถูกซ่อนไว้ในขณะนี้ ต้องบอกว่านักพัฒนาบางรายกำลังสร้างโครงการที่น่าสนใจโดยใช้เช่นไคลเอนต์ IRC นี้นี้

ในการเข้าถึง API นี้คุณจะต้องเปิดใช้งานการตั้งค่าสถานะทดลองในรายการส่วนขยายของคุณ การใช้ซ็อกเก็ตนั้นค่อนข้างตรงไปตรงมาเช่น:

chrome.experimental.socket.create('tcp', '127.0.0.1', 8080, function(socketInfo) {
  chrome.experimental.socket.connect(socketInfo.socketId, function (result) {
        chrome.experimental.socket.write(socketInfo.socketId, "Hello, world!");         
    });
});

เบราว์เซอร์ใดรองรับซ็อกเก็ตดิบ
AlikElzin-kilaka

2
ประสิทธิภาพเพิ่มขึ้นเมื่อเทียบกับ Websockets และ Rawsockets หรือไม่?
NiCk Newman

3
ไม่อนุญาตให้ javascript ในเบราว์เซอร์เชื่อมต่อกับพอร์ต tcp ซึ่งเป็นช่องโหว่ด้านความปลอดภัยหรือไม่? ลองนึกภาพ javascript ใน firefox / chrome ของคุณเชื่อมต่อกับทุกสิ่งที่คุณเรียกใช้ในเครื่อง (เช่น MySQL DB) และเผยแพร่ข้อมูลไปยังไซต์ที่ชั่วร้าย?
อรุณอวานาธาน

@ArunAvanathan ไม่ว่าคุณจะทำอะไรกับ ajax คุณสามารถทำได้ด้วยซ็อกเก็ตและหนีบในทางกลับกัน ... ไม่มีปัญหาด้านความปลอดภัยอย่างที่ฉันคิด
Firas Abd Alrahman

1
@FirasAbdAlrahman ฉันคิดว่ามีนโยบายความปลอดภัยต่างๆที่ควบคุมพฤติกรรมของเบราว์เซอร์สำหรับ HTTP / S ดังนั้นการเชื่อมต่อซ็อกเก็ตเบราว์เซอร์ผ่าน TCP จึงไม่เหมือนกับ HTTP / S
Arun Avanathan

30

สิ่งนี้สามารถทำได้ผ่านอินเทอร์เฟซเนวิเกเตอร์ดังที่แสดงด้านล่าง:

navigator.tcpPermission.requestPermission({remoteAddress:"127.0.0.1", remotePort:6789}).then(
  () => {
    // Permission was granted
    // Create a new TCP client socket and connect to remote host
    var mySocket = new TCPSocket("127.0.0.1", 6789);

    // Send data to server
    mySocket.writeable.write("Hello World").then(
        () => {

            // Data sent sucessfully, wait for response
            console.log("Data has been sent to server");
            mySocket.readable.getReader().read().then(
                ({ value, done }) => {
                    if (!done) {
                        // Response received, log it:
                        console.log("Data received from server:" + value);
                    }

                    // Close the TCP connection
                    mySocket.close();
                }
            );
        },
        e => console.error("Sending error: ", e)
    );
  }
);

รายละเอียดเพิ่มเติมระบุไว้ในเอกสาร w3.org tcp-udp-sockets

http://raw-sockets.sysapps.org/#interface-tcpsocket

https://www.w3.org/TR/tcp-udp-sockets/

อีกทางเลือกหนึ่งคือการใช้Chrome Sockets

การสร้างการเชื่อมต่อ

chrome.sockets.tcp.create({}, function(createInfo) {
  chrome.sockets.tcp.connect(createInfo.socketId,
    IP, PORT, onConnectedCallback);
});

การส่งข้อมูล

chrome.sockets.tcp.send(socketId, arrayBuffer, onSentCallback);

การรับข้อมูล

chrome.sockets.tcp.onReceive.addListener(function(info) {
  if (info.socketId != socketId)
    return;
  // info.data is an arrayBuffer.
});

คุณสามารถใช้ความพยายามในการใช้งานได้ด้วยHTML5 Web Sockets(แม้ว่านี่จะไม่ใช่การสื่อสาร TCP โดยตรง):

var connection = new WebSocket('ws://IPAddress:Port');

connection.onopen = function () {
  connection.send('Ping'); // Send the message 'Ping' to the server
};

http://www.html5rocks.com/en/tutorials/websockets/basics/

เซิร์ฟเวอร์ของคุณต้องรับฟังด้วยเซิร์ฟเวอร์ WebSocket เช่น pywebsocket หรือคุณสามารถเขียนของคุณเองตามที่ระบุไว้ที่Mozilla


25
เพื่ออธิบายรายละเอียดเพิ่มเติมเกี่ยวกับคำตอบนี้: เซิร์ฟเวอร์จะต้องรับฟังด้วยเซิร์ฟเวอร์ WebSocket WebSockets ไม่สามารถเชื่อมต่อโดยตรงกับซ็อกเก็ต TCP ดิบ websockify เป็นเครื่องมือที่ทำหน้าที่เป็นพร็อกซี WebSocket-to-TCP: อยู่บนเซิร์ฟเวอร์ของคุณและรับฟังการเชื่อมต่อ WebSocket จากนั้นส่งต่อการสื่อสาร WebSocket ไปยังและจากซ็อกเก็ต TCP ที่ระบุ
apsillers

58
สิ่งนี้ไม่ตอบคำถาม - websocket เป็นโปรโตคอลผ่าน TCP (เช่น HTTP เป็นต้น) และไม่ใช่การสื่อสาร TCP โดยตรง
AlikElzin-kilaka

1
แต่จะใส่ข้อความในหน้าต่างเบราว์เซอร์ได้อย่างไร? :(
shzyincu

3
คำตอบนี้ผิดทั้งหมดและควรลบทิ้ง
Brad

1
@ แบรดคำตอบนี้ช่วยฉันได้และต้องช่วยคนอื่น ๆ ที่มี 22 upvotes ด้วย
user1378687

6

โครงการws2sมีวัตถุประสงค์เพื่อนำซ็อกเก็ตไปยัง js ฝั่งเบราว์เซอร์ เป็นเซิร์ฟเวอร์ websocket ที่เปลี่ยน websocket เป็นซ็อกเก็ต

แผนภาพ ws2s

ใส่คำอธิบายภาพที่นี่

ตัวอย่างโค้ด:

var socket = new WS2S("wss://ws2s.feling.io/").newSocket()

socket.onReady = () => {
  socket.connect("feling.io", 80)
  socket.send("GET / HTTP/1.1\r\nHost: feling.io\r\nConnection: close\r\n\r\n")
}

socket.onRecv = (data) => {
  console.log('onRecv', data)
}

5

ดูjsocket jsocketยังไม่ได้ใช้เอง. ใช้เวลามากกว่า 3 ปีนับตั้งแต่การอัปเดตครั้งล่าสุด (ณ วันที่ 26/6/2557)

* ใช้แฟลช :(

จากเอกสารประกอบ :

<script type='text/javascript'>
    // Host we are connecting to
    var host = 'localhost'; 
    // Port we are connecting on
    var port = 3000;

    var socket = new jSocket();

    // When the socket is added the to document 
    socket.onReady = function(){
            socket.connect(host, port);             
    }

    // Connection attempt finished
    socket.onConnect = function(success, msg){
            if(success){
                    // Send something to the socket
                    socket.write('Hello world');            
            }else{
                    alert('Connection to the server could not be estabilished: ' + msg);            
            }       
    }
    socket.onData = function(data){
            alert('Received from socket: '+data);   
    }

    // Setup our socket in the div with the id="socket"
    socket.setup('mySocket');       
</script>

0

ทางออกที่คุณกำลังมองหาคือเว็บซ็อกเก็ต อย่างไรก็ตามโครงการโครเมียมได้พัฒนาเทคโนโลยีใหม่ ๆ ซึ่งเป็นการเชื่อมต่อ TCP โดยตรงโครเมี่ยม TCP


0

เพื่อให้บรรลุสิ่งที่คุณต้องการคุณจะต้องเขียนสองแอปพลิเคชัน (ใน Java หรือ Python เป็นต้น):

  1. แอปบริดจ์ที่อยู่ในเครื่องของลูกค้าและสามารถจัดการกับซ็อกเก็ต TCP / IP และ WebSockets มันจะโต้ตอบกับซ็อกเก็ต TCP / IP ที่เป็นปัญหา

  2. แอปฝั่งเซิร์ฟเวอร์ (เช่น JSP / Servlet WAR) ที่สามารถพูดคุยกับ WebSockets ประกอบด้วยหน้า HTML อย่างน้อยหนึ่งหน้า (รวมถึงรหัสการประมวลผลฝั่งเซิร์ฟเวอร์หากจำเป็น) ที่จะเข้าถึงได้โดยเบราว์เซอร์

มันควรจะทำงานเช่นนี้

  1. Bridge จะเปิดการเชื่อมต่อ WS ไปยังเว็บแอป (เนื่องจากเซิร์ฟเวอร์ไม่สามารถเชื่อมต่อกับไคลเอนต์)
  2. เว็บแอปจะขอให้ลูกค้าระบุตัวเอง
  3. ไคลเอนต์บริดจ์ส่งข้อมูล ID บางส่วนไปยังเซิร์ฟเวอร์ซึ่งจัดเก็บข้อมูลเพื่อระบุบริดจ์
    1. เพจที่สามารถดูได้ของเบราว์เซอร์เชื่อมต่อกับเซิร์ฟเวอร์ WS โดยใช้ JS
    2. ทำซ้ำขั้นตอนที่ 3 แต่สำหรับเพจที่ใช้ JS
    3. เพจที่ใช้ JS จะส่งคำสั่งไปยังเซิร์ฟเวอร์รวมถึงบริดจ์ที่ต้องไป
    4. เซิร์ฟเวอร์ส่งต่อคำสั่งไปยังบริดจ์
    5. บริดจ์เปิดซ็อกเก็ต TCP / IP และโต้ตอบกับมัน (ส่งข้อความรับคำตอบ)
    6. Bridge ส่งการตอบกลับไปยังเซิร์ฟเวอร์ผ่าน WS
    7. WS ส่งต่อการตอบสนองไปยังเพจที่สามารถดูได้ของเบราว์เซอร์
    8. JS ประมวลผลการตอบสนองและตอบสนองตามนั้น
    9. ทำซ้ำจนกว่าไคลเอ็นต์จะยกเลิกการเชื่อมต่อ / ยกเลิกการโหลด

หมายเหตุ 1:ขั้นตอนข้างต้นเป็นการทำให้เข้าใจง่ายขึ้นอย่างมากและไม่รวมข้อมูลเกี่ยวกับการจัดการข้อผิดพลาดและคำขอ keepAlive ในกรณีที่ไคลเอนต์ยกเลิกการเชื่อมต่อก่อนเวลาอันควรหรือเซิร์ฟเวอร์จำเป็นต้องแจ้งให้ไคลเอ็นต์ทราบว่ากำลังปิด / รีสตาร์ท

หมายเหตุ 2:ขึ้นอยู่กับความต้องการของคุณอาจเป็นไปได้ที่จะรวมส่วนประกอบเหล่านี้เข้าด้วยกันหากเซิร์ฟเวอร์ซ็อกเก็ต TCP / IP ที่เป็นปัญหา (ซึ่งบริดจ์พูดถึง) อยู่บนเครื่องเดียวกันกับแอปเซิร์ฟเวอร์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.