国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

設備改造——上傳結果數(shù)據(jù)的技術實現(xiàn)

Mr_houzi / 2933人閱讀

摘要:設備改造上傳結果數(shù)據(jù)的技術實現(xiàn)一項目需求及分析按照領導的要求,要改造一臺儀器,添加點功能,將測量數(shù)據(jù)上傳到服務器。所以選擇用提交,的通信可以多線程調(diào)度。考慮到新增的上傳功能不能影響之前的測量節(jié)拍,所以要多線程實現(xiàn)。

**設備改造——上傳結果數(shù)據(jù)的技術實現(xiàn) 一、項目需求及分析

按照領導的要求,要改造一臺儀器,添加點功能,將測量數(shù)據(jù)上傳到服務器。儀器測量節(jié)拍大概是20s,數(shù)據(jù)量目前不大,每次測量大概不到2M左右,且都是浮點數(shù)據(jù)和整形數(shù)據(jù)。

起初想用TCP長連接實現(xiàn)的,但考慮到現(xiàn)場環(huán)境。典型的制造業(yè)車間,電磁環(huán)境復雜,網(wǎng)絡信號不穩(wěn),所以不考慮TCP長連接實現(xiàn)。短連接也不在考慮范圍內(nèi),以后儀器數(shù)量多了之后頻繁的建立連接開銷也很大,服務器有可能受不了(阿里云的乞丐版)。所以選擇用restful提交,http的通信可以多線程調(diào)度。

儀器控制程序是C#開發(fā)的,所以客戶端最好是c#。服務端我想用springboot,很方便。

考慮到新增的上傳功能不能影響之前的測量節(jié)拍,所以要多線程實現(xiàn)??上矣趾軕校幌肟紤]線程協(xié)調(diào)問題,最后選擇消息隊列實現(xiàn)。

考慮到節(jié)省流量(服務器是按流量收費的),文件要壓縮,C#下要實現(xiàn)文件壓縮功能。

從測量文件中讀取數(shù)據(jù),將參數(shù)存入數(shù)據(jù)庫,測量原始數(shù)據(jù)打包放在文件服務器上。

二、整體架構和技術方案

最后的技術方案就是C#做客戶端,java構建服務端restful API進行上傳

整體架構如下圖:

使用的技術如下:

C#的Restful客戶端:RestSharp

java的Restful服務端:springboot

C#端消息隊列:NetMQ

C#端zip操作組件:DotNetZip

java端zip操作組件:Apache Commons Compress

三、服務端

服務端采用springboot的restful,POST方式,非常簡單。
傳輸文件采用MultipartFile方式,因為客戶端的ResrSharp只能采用這種方式傳遞文件

@RestController
@RequestMapping(value = "upload")
public class FileRestController {
    Logger logger = LogManager.getLogger(FileRestController.class);

    @RequestMapping(value = "file", method = RequestMethod.POST)
    public
    @ResponseBody
    RestResult getZipFile(@RequestParam("file") MultipartFile file) throws IOException, URISyntaxException {
        RestResult result = new RestResult();
        if (!file.getName().isEmpty()) {
            InputStream stream = file.getInputStream();
//            String directory = FileRestController.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
            String directory = "/usr/local/haliang/files/";
            try {
                directory = URLDecoder.decode(directory, "utf-8");
            } catch (java.io.UnsupportedEncodingException e) {
                return null;
            }
            FileOutputStream fs = new FileOutputStream(directory + file.getOriginalFilename());
            logger.info("文件所在的目錄:   " + directory + "/files/" + file.getOriginalFilename());
            byte[] buffer = new byte[1024 * 1024];
            int bytesum = 0;
            int byteread = 0;
            while ((byteread = stream.read(buffer)) != -1) {
                bytesum += byteread;
                fs.write(buffer, 0, byteread);
                fs.flush();
            }
            fs.close();
            stream.close();
            logger.info("成功接收文件:   " + directory + file.getOriginalFilename());
        }

        return result;
    }
}
四、客戶端

客戶端架構如下圖:

1 zeromq簡介

NetMQ 是 ZeroMQ的C#移植版本。

1.1:zeromq是什么

NetMQ (ZeroMQ to .Net),ZMQ號稱史上最快中間件。
它對socket通信進行了封裝,使得我們不需要寫socket函數(shù)調(diào)用就能完成復雜的網(wǎng)絡通信。
它跟Socket的區(qū)別是:普通的socket是端到端的(1:1的關系),而ZMQ卻是可以N:M的關系,人們對BSD套接字的了解較多的是點對點的連接,點對點連接需要顯式地建立連接、銷毀連接、選擇協(xié)議(TCP/UDP)和處理錯誤等,而ZMQ屏蔽了這些細節(jié),讓你的網(wǎng)絡編程更為簡單。
它是一個消息處理隊列庫,可在多個線程、內(nèi)核和主機盒之間彈性伸縮。和一般意義上的消息隊列產(chǎn)品不同的是,它沒有消息隊列服務器,而更像是一個網(wǎng)絡通信庫。從網(wǎng)絡通信的角度看,它處于會話層之上,應用層之下,屬于傳輸層。

1.2:zeromq的消息模型

zeromq將消息通信分為4種模型,分別是一對一結對模型(Exclusive-Pair)、請求回應模型(Request-Reply)、發(fā)布訂閱模型(Publish-Subscribe)、推拉模型(Push-Pull)。這4種模型總結出了通用的網(wǎng)絡通信模型,在實際中可以根據(jù)應用需要,組合其中的2種或多種模型來形成自己的解決方案。

1.2.1 一對一結對模型 Exclusive-Pair

最簡單的1:1消息通信模型,用來支持傳統(tǒng)的 TCP socket模型,主要用于進程內(nèi)部線程間通信??梢哉J為是一個TCP Connection,但是TCP Server只能接受一個連接。采用了lock free實現(xiàn),速度很快。數(shù)據(jù)可以雙向流動,這點不同于后面的請求響應模型。(不推薦使用,沒有例子)

1.2.2 請求回應模型 Request-Reply

由請求端發(fā)起請求,然后等待回應端應答。一個請求必須對應一個回應,從請求端的角度來看是發(fā)-收配對,從回應端的角度是收-發(fā)對。跟一對一結對模型的區(qū)別在于請求端可以是1~N個。
請求端和回應端都可以是1:N的模型。通常把1認為是server,N認為是Client。ZeroMQ可以很好的支持路由功能(實現(xiàn)路由功能的組件叫作Device),把1:N擴展為N:M(只需要加入若干路由節(jié)點)。從這個模型看,更底層的端點地址是對上層隱藏的。每個請求都隱含有回應地址,而應用則不關心它。通常把該模型主要用于遠程調(diào)用及任務分配等。
(NetMQ請求響應C#調(diào)用案例)

1.2.3 發(fā)布訂閱模型 Publisher-Subscriber(本項目采用的模型)

發(fā)布端單向分發(fā)數(shù)據(jù),且不關心是否把全部信息發(fā)送給訂閱端。如果發(fā)布端開始發(fā)布信息時,訂閱端尚未連接上來,則這些信息會被直接丟棄。訂閱端未連接導致信息丟失的問題,可以通過與請求回應模型組合來解決。訂閱端只負責接收,而不能反饋,且在訂閱端消費速度慢于發(fā)布端的情況下,會在訂閱端堆積數(shù)據(jù)。該模型主要用于數(shù)據(jù)分發(fā)。天氣預報、微博明星粉絲可以應用這種經(jīng)典模型。 (NetMQ發(fā)布訂閱模式C#調(diào)用案例)

1.2.4 推拉模型 Push-Pull

Server端作為Push端,而Client端作為Pull端,如果有多個Client端同時連接到Server端,則Server端會在內(nèi)部做一個負載均衡,采用平均分配的算法,將所有消息均衡發(fā)布到Client端上。與發(fā)布訂閱模型相比,推拉模型在沒有消費者的情況下,發(fā)布的消息不會被消耗掉;在消費者能力不夠的情況下,能夠提供多消費者并行消費解決方案。該模型主要用于多任務并行。
(NetMQ推拉模式C#調(diào)用案例)

1.3:zeromq的優(yōu)勢

TCP:ZeroMQ基于消息,消息模式,而非字節(jié)流。

XMPP:ZeroMQ更簡單、快速、更底層。Jabber可建在ZeroMQ之上。

AMQP:完成相同的工作,ZeroMQ要快100倍,而且不需要代理(規(guī)范更簡潔——少278頁)

IPC:ZeroMQ可以跨多個主機盒,而非單臺機器。

CORBA:ZeroMQ不會將復雜到恐怖的消息格式強加于你。

RPC:ZeroMQ完全是異步的,你可以隨時增加/刪除參與者。

RFC 1149:ZeroMQ比它快多了!

29west LBM:ZeroMQ是自由軟件!

IBM低延遲:ZeroMQ是自由軟件!

Tibco:仍然是自由軟件!

2.代碼實現(xiàn) 2.1 Publisher(發(fā)布者)

一般都是發(fā)布者先啟動,綁定監(jiān)聽端口。封裝了一個發(fā)送函數(shù),主要是發(fā)送原先軟件生成測量文件的路徑。

public class Publisher
    {
        public int Port { get; set; }
        private PublisherSocket socket;

        /// 
        /// 構造函數(shù)
        /// 
        /// 綁定的端口
        public Publisher(int port)
        {
            Port = port;
        }

        /// 
        /// 啟動發(fā)布端
        /// 
        public void Start()
        {
            NetMQContext context = NetMQContext.Create();
            this.socket = context.CreatePublisherSocket();
            this.socket.Bind("tcp://127.0.0.1:" + Port);
        }

        /// 
        /// 發(fā)送數(shù)據(jù)
        /// 
        /// 
        public void Send(string result)
        {
            socket.SendFrame(result);
        }
    }
2.2 Subscriber(訂閱者)

訂閱者啟動時候連接端口。防止線程阻塞,訂閱者是新開一個線程運行的。

public class Subscribe
    {
        private delegate void GetDataHandler(string message);

        private event GetDataHandler onGetData;
        public int Port { get; set; }
        public string TempDirectory { get; set; }
        public bool isRunning { get; set; }
        public string domain { get; set; }

        public Subscribe(int port, string domain)
        {
            Port = port;
            this.domain = domain;
            onGetData += ProcessData;
        }

        private SubscriberSocket socket;

        public void Start()
        {
            this.isRunning = true;
            NetMQContext context = NetMQContext.Create();
            socket = context.CreateSubscriberSocket();
            socket.Connect("tcp://127.0.0.1:" + Port);
            socket.Subscribe("");
            Thread t = new Thread(new ThreadStart(StartSub));
            t.Start();
        }

        private void StartSub()
        {
            while (isRunning)
            {
                Thread.Sleep(10000);
                string result = socket.ReceiveFrameString(Encoding.UTF8);
                onGetData(result);
            }
        }

        private void ProcessData(string path)
        {
            Console.WriteLine("收到文件:" + path);
            string compressedFile = Compress.CompressFile(TempDirectory, path);
            new RestPost(domain).Post(compressedFile);
        }
3 客戶端壓縮

壓縮使用DotNetZip組件,非常簡單好用。

 public class Compress
    {
        public static string CompressFile(string temp,string txtPath)
        {
            string txtFileName = System.IO.Path.GetFileNameWithoutExtension(txtPath);
            string compressedFileName = temp+"/"+txtFileName + ".zip";
            ZipFile file=new ZipFile();
            file.AddFile(txtPath,"");
            file.Save(compressedFileName);
            return compressedFileName;
        }
    }
4 客戶端上傳

使用RestSharp組件,也是非常簡單。異步回調(diào),不影響性能。

public class RestPost
    {
        public string Domain { get; set; }

        public RestPost(string domain)
        {
            Domain = domain;
        }

        public void Post(string path)
        {
            RestRequest request = new RestRequest(Method.POST);
            request.AddFile("file", path);
            RestClient client = new RestClient {BaseUrl = new Uri("http://" + Domain + "/upload/file")};
            client.ExecuteAsync(request, (response) =>
                {
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        Console.WriteLine("上傳成功...
" + response.Content);
                    }
                    else
                    {
                        Console.WriteLine($"出錯啦:{response.Content}");
                    }
                }
            );
        }
    }
五、總結

寫代碼之前一定要搞清楚需求,設計好架構

注意消息隊列啟動時候的線程問題

異步執(zhí)行

文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/76487.html

相關文章

  • 首次揭秘!阿里無人店系統(tǒng)背后技術

    摘要:下面,我們邀請阿里巴巴淘寶技術部資深技術專家,天貓未來店技術負責人時維,為大家分享天貓未來店背后的技術本文根據(jù)云棲大會演講整理而成??偨Y下來,阿里無人店開發(fā)的宗旨就是兩句話首先,技術上我是要追求無人的能力,但不迎合無人的體驗。 showImg(https://segmentfault.com/img/remote/1460000016760894); 今年云棲大會現(xiàn)場一大網(wǎng)紅打卡地莫過...

    littleGrow 評論0 收藏0
  • 淺談物聯(lián)網(wǎng)技術

    摘要:物聯(lián)網(wǎng)技術四層面對于標準的物聯(lián)網(wǎng)系統(tǒng),可以分為四層感知識別層網(wǎng)絡構建層管理服務層和綜合應用層。網(wǎng)絡構建層數(shù)據(jù)傳輸網(wǎng)絡是物聯(lián)網(wǎng)最重要的基礎設施之一。 1.1什么是物聯(lián)網(wǎng) ????????從字面意思來說十分好理解——萬物相連的互聯(lián)網(wǎng),其實就是將日常生活中的一些設備以數(shù)字化方式連接世界的方式。這些...

    QLQ 評論0 收藏0
  • 借evdev之力 Linux全局熱鍵魔改造

    摘要:開始動工就我的需求而言,我腦子里第一個浮現(xiàn)的抽象機制就是狀態(tài)機,不知為何。一個比較合適的設計是兩層的自動機,第一層用來為這三個一組的事件分組,分好組之后成為第二層狀態(tài)機的輸入,一個二元組。 霓虹語標題我都想好了。evdevの力を貸して、Linuxでホットキーの魔改造 Linux用戶就像Minecraft玩家,雖然大家玩的都是Minecraft,但是,臥槽,我們一定是在玩不同的游戲(見到...

    Half 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<