iT邦幫忙

0

Python 的 Socket 如何跟 Nginx 搭配,還是不需要 Nginx ?

  • 分享至 

  • xImage

這裡不是指 DjangoFlask

Python 本身的 Socket 套件。

但我有用過 Nginx + uwsgi or gunicorn + Django or Flask 過。

今天因為要改用 Socket 傳資料,只要最初連線一次後,就能一直雙通傳資料比較快。

但是網路管理員不願意開除了 80 Port 以外的 Port 給我,希望我將 SocketNginx 搭起來。

但是我完全不知道怎麼搭??

例如 Djangowsgi.pyFlaskapp = Flask(__name__),之後用 uwsgigunicorn 串接起來就好了。

Socket 怎麼串?

Google 了很多 Python Socket + Nginx 都是 DjangoFlask 的相關資訊。

求人給個參考文章參考...

簡單來講就是

Nginx -> 80port

我的 Socket Server -> Host: 192.168.x.xxx, Port:9000

client(80 Port) -> Nginx(80port) -> Socket(9000port) -> Nginx(80port) -> client(80 Port)

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

6
japhenchen
iT邦超人 1 級 ‧ 2021-04-23 08:01:18
最佳解答

客戶端Form POST ←→ NGINX ←→ PHP ←→ EXEC PYTHON

從頭到尾只要80或443,不需要任何socket,PHP用EXEC調用PYTHON,PYTHON以print(json)回傳值給PHP的調用,PHP再把接收到的回傳值回應給客戶

我前陣子有提到的幾個作品都用到這個作法,而都不用socket

<?php
if (isset($_POST["action"])) {
    $action = $_POST["action"];
    $value = $_POST["data"];
    if ($action === "POSTPYTHON") {    
        echo exec("/usr/bin/python3 /home/userxxx/gggg.py  '".$value."'");
        die();
        exit();   
    } 
}
?>

至於python那裡你只要做print()回傳執行結果就好,exec()會處理接收

客戶端你只要能用一般的webclient/httprequest getstring by post就能搞定,所以建議用共通格式json來傳遞

看更多先前的回應...收起先前的回應...

我寫php用到python的原因,就是python可以調用selenium抓別人的網頁的資料,達到即時爬蟲又不用煩惱被"我不是機器人"擋下

如果是WEB Service base on Windows的環境做這種方法,會有亂碼的的問題,在客戶端做encode/decodeuri可解決這個問題

sma739146 iT邦新手 5 級 ‧ 2021-04-23 08:59:50 檢舉

我沒有要開網頁傳送資料,後端與後端兩個不同地方傳送資料。

那就不用nginx,你直接用python開socket監聽80端口

如果你要使用python的機器上已有nginx且有在正常工作,那你無法再用python去監聽80,會報端口已被佔用鍞定的錯誤,除非你有辦法把nginx移除(呃!)不然應該無解

https://shengyu7697.github.io/python-tcp-socket/

我回應的例子就是因為公司不允許任意開防火牆端口(映射、對應虛擬伺服器)使用,也不能任意開新電腦拿實體IP,可用的主機上都有各式各樣的伺服軟體在跑不能隨便移除,我只能用webapi(php) + python的方法來折中,跟有沒有要架網站無關,老板不開這個門,我就開另一扇窗而已

解決問題不只可以用【正統、正宗、名門正派】的方法去解決,有時旁門左道,會更好用!

sma739146 iT邦新手 5 級 ‧ 2021-04-23 10:51:19 檢舉

哦!我的Nginx80 port 是要給架設 Django 的網站用的不能移除,但要在一個機器上 run DjangoServer 以及 SocketServer 。

django 裡弄個特殊的頁面跑你的python,不行嗎?

sma739146 iT邦新手 5 級 ‧ 2021-04-23 14:10:11 檢舉

可是我沒有要用網頁傳送資料,是外部的後端連到Server後端傳送資料。

咳............有誰跟你說WebAPI/Service就是做給人看的網頁?很多人(我也會)寫程式也會用IIS/Apache/nginx 上建一個WebAPI,用httprequests來傳遞資料,不用為了傳資料,要費心學學Socket還要另外在防火牆上開映射或多綁一個IP

這個是我放在公司在外面工地工務所裡的樹莓派裡的python程式,主要的工作就是把工地的指紋機裡的出勤記錄,定時從機器上下載,打包後POST總公司網站IIS裡的WebAPI

def addenroll(attlog, mid):
    url = "http://erp.XXXXXXXX.com.tw/addenroll.aspx"
    if isinstance(attlog, list):
        #開始回存記錄到伺服器
        loglist = list()
        logpost = "["
        vlen = len(attlog)
        for l in range(vlen):
            log = attlog[l]
            xd = log[2]
            logitem = '"{0},{1},{2},{3},1,{4},0,{5}"'.format(xd.strftime(
                "%Y,%m,%d"), xd.strftime("%H,%M,%S"), str(1000+mid), log[0], log[1], mid)
            logpost += logitem
            loglist.append(logitem)
            if l < (vlen-1):
                logpost += ","                
        logpost += "]"

        resp = requests.post(url, data={"PostEnrollRecords": logpost})
    return


# ZK就是我家的指紋機,自己寫的class處理設備連接驅動
mid = 55 
#55是設備編號,每台都有一個唯一的編號,存進資料庫後,我才知道是誰按了哪一個工務所的指紋機啊~~
zk.connect()
if zk.isconnect:
    attlogs = zk.getAttendance()  
    if attlogs != False:
        addenroll(attlogs, mid)
        zk.disconnect()

例子裡的 addenroll.aspx 就是我講的 WebAPI ..
處理的事也很簡單,把Client端(樹莓派)post來的資料,解構json後回存資料庫

sma739146 iT邦新手 5 級 ‧ 2021-04-23 16:25:40 檢舉

好的!我知道了!我研究 WebSocket 怎麼寫 Server 與 Client !

4
froce
iT邦大師 1 級 ‧ 2021-04-23 08:01:15

websocket應該比較適合你。
下面這是yarn run dev起來,測試伺服器用來做hot reload的websocket設定,你可以參考看看。
基本上就是websocket會走/sockjs-node這條路由,然後導向後端server的ip和port。

location /sockjs-node {
            proxy_set_header X-Real-IP  $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;

            proxy_pass http://localhost:8080;

            proxy_redirect off;

            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
看更多先前的回應...收起先前的回應...
sma739146 iT邦新手 5 級 ‧ 2021-04-23 08:57:20 檢舉

我現在不會寫 Web-Socket,沒有範例的 server.py與 client.py,現階段我只能用 純 Socket寫 ,並且我沒有要開網頁傳資料,都是後端與後端傳送資料。

sma739146 iT邦新手 5 級 ‧ 2021-04-23 08:59:07 檢舉

我不清楚 sockjs-node 是怎麼出來的,我只能用 Python 寫。

froce iT邦大師 1 級 ‧ 2021-04-23 14:03:31 檢舉

你還是詳細敘述你到底要幹麻?
你要在網頁上傳資料?要像網頁聊天軟體一樣?還是要透過 internet 傳socket控制機器(是的話我也只能說你很大膽)?

在網頁上的即時應用,我建議你去查websocket。
要透過網頁控制機器,可以像下面japhenchen大的方法去做。

sma739146 iT邦新手 5 級 ‧ 2021-04-23 14:08:52 檢舉

我沒有要在網頁上傳資料,是要通過外部的 Client 透過 internet 傳到 ServerSocket 接著 Server Socket 回傳資料給 Client。

froce iT邦大師 1 級 ‧ 2021-04-23 16:01:04 檢舉

你敢在網際網路傳socket...我真的只能說你很大膽。

依你的使用狀況
這樣建議server做webapi傳json,client post資料給web server,然後傳回資料就好。

sma739146 iT邦新手 5 級 ‧ 2021-04-23 16:24:20 檢舉

哦哦,看來不能用 socket 傳送資料只能學 ServerSocket 了!

froce iT邦大師 1 級 ‧ 2021-04-23 16:36:25 檢舉

不,你不需要任何socket的東西啊...

只要你的 client 送出post 給 web server,然後web server回傳結果就行。

不過你要用websocket其實也行啦

sma739146 iT邦新手 5 級 ‧ 2021-04-23 20:11:15 檢舉

一定要用 Socket ,我現在是用一般的 HttpApi 從 Client 給 Server 後拿到答案要花0.2 ~ 0.4秒,主管叫我再快一點,叫我用 Websocket 做,但我當時沒聽清楚是 WebSocket,但我都寫好 Socket 版本了。

sma739146 iT邦新手 5 級 ‧ 2021-04-23 20:15:16 檢舉

我 Server 處理資料時間只要0.05秒,主要是一直跟 Server 連線一次太耗時了。

我要發表回答

立即登入回答