# Δημοσιεύστε έναν τοπικό διακομιστή μέσω σήραγγας με τα PROXYSERVER() και PROXYCLIENT()

> Αφήστε έναν διακομιστή Total.js με δημόσια διεύθυνση να προωθεί αιτήματα σε ένα πρόγραμμα που τρέχει μόνο σε ιδιωτικό μηχάνημα, με μια σήραγγα WebSocket που ανοίγει η ιδιωτική πλευρά.

Framework: total5
Product: Total.js 5 (total5@0.0.19)
Language: el
Content-SHA256: 5d9e89fdf606fee586c0277fe0b795bf4d080156024f15560b25062f65f6064c
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: total5-installed@total5@0.0.19
Review: not-recorded

Το `PROXY()` προωθεί ένα αίτημα σε έναν διακομιστή που το proxy μπορεί να φτάσει. Μια σήραγγα είναι για την αντίστροφη περίπτωση: το πρόγραμμα βρίσκεται σε ένα φορητό ή πίσω από ένα τείχος προστασίας, οπότε κανείς δεν μπορεί να συνδεθεί σε αυτό, αλλά μπορεί να συνδεθεί προς τα έξω. Τα `PROXYSERVER()` και `PROXYCLIENT()` το πετυχαίνουν με ένα WebSocket που ανοίγει η ιδιωτική πλευρά:

- Το `PROXYSERVER([endpoint], [socketendpoint], [logger])` τρέχει στον δημόσιο διακομιστή. Κάθε αίτημα κάτω από το `endpoint` (προεπιλογή `/`) στέλνεται μέσω της σήραγγας· το `socketendpoint` (προεπιλογή `/`) είναι η διεύθυνση WebSocket όπου συνδέεται ο client. Χρησιμοποιήστε **διαφορετικές** διευθύνσεις όταν η ίδια εφαρμογή εξυπηρετεί και κάτι άλλο: ένα proxy στο `/` παίρνει κάθε αίτημα, ακόμη και των δικών σας διαδρομών (τρέχει πριν από αυτές). Το `logger` είναι μια συνάρτηση (προεπιλογή: τυπώνει με ημερομηνία)· περάστε `null` για κανένα.
- Το `PROXYCLIENT(serverurl, port, [logger])` τρέχει στην ιδιωτική πλευρά (σε αυτό το παράδειγμα η διεύθυνση του διακομιστή φτιάχνεται με το `CONF.$port`, τη θύρα της εφαρμογής). Το `serverurl` είναι η διεύθυνση WebSocket του διακομιστή (`ws://` ή `wss://`· το `http` αλλάζει σε `ws`) και το `port` είναι `3000` ή `ip:3000`, το τοπικό πρόγραμμα που λαμβάνει τα αιτήματα. Επιστρέφει τον client WebSocket.
- **Ένας client τη φορά:** όταν συνδεθεί δεύτερος client, ο διακομιστής τον κλείνει με τον κωδικό `4001`. Χωρίς client η απάντηση του διακομιστή είναι `Not yet available.`.
- Το τοπικό πρόγραμμα λαμβάνει την **πλήρη διαδρομή του αρχικού αιτήματος**, συμπεριλαμβανομένου του `endpoint` (`/tunnel/hello`), τις κεφαλίδες του επισκέπτη και μια κεφαλίδα `x-proxy: Total.js`, με το `host` ορισμένο στην τοπική διεύθυνση.
- Η διαδρομή WebSocket δεν έχει δική της πιστοποίηση: μην τη δημοσιεύετε χωρίς κάτι μπροστά της που αποφασίζει ποιος μπορεί να συνδεθεί (η διεύθυνση ως μυστικό, ένα δικό σας `check`, ένα τείχος προστασίας).

Εδώ μία εφαρμογή είναι και οι δύο πλευρές: ένα μικρό τοπικό πρόγραμμα στη θύρα 9511 (οποιοδήποτε πρόγραμμα θα έκανε), ο διακομιστής στο `/tunnel/` και ο client που συνδέεται στην ίδια εφαρμογή.

```js definitions/local.js
// The program that is "private": an ordinary HTTP server that only listens on the loopback address
require('http').createServer(function(req, res) {
	res.writeHead(200, { 'content-type': 'application/json' });
	res.end(JSON.stringify({ path: req.url, via: req.headers['x-proxy'] || null, host: req.headers.host }));
}).listen(9511, '127.0.0.1');
```

```js controllers/tunnel.js
exports.install = function() {
	ROUTE('GET /status/', status);
	ROUTE('POST /connect/', connect);
};

// The public side: /tunnel/* goes through the tunnel, the WebSocket of the client is /tunnel-socket/. No logger.
PROXYSERVER('/tunnel/', '/tunnel-socket/', null);

let client = null;

function connect($) {
	client = PROXYCLIENT('ws://127.0.0.1:' + CONF.$port + '/tunnel-socket/', '9511', null);
	$.json({ connecting: true });
}

function status($) {
	$.json({ connected: !!client });
}
```
