1、 引子html
寫這個開源系列已經十來篇了。自從十年前註冊博客園以來,關注了張善友、老趙、xiaotie、深藍色右手等一衆大牛,也圍觀了逗比的吉日嘎啦、精密頑石等形形色色的園友。然而整整十年一篇文章都沒有寫過,屬於很是努力的在社區汲取養分的菜青蟲一隻,如今也算破繭而出了,雖然遠沒有得道化蝶的境界,也在寫做過程當中獲得很多提高。我開源的這個項目也有我固有的不良代碼風格:嚴重缺少註釋,一方面是懶,一方面由於是單兵做戰,也不曾想過讓別人理解本身的代碼。如何用簡潔明瞭的方式表達本身的思路,雖然燒腦,但獲得了社區的初步承認,在激勵我把這個系列堅持下去的同時,對下一步如何完善這個項目,思路也更加清晰了。mysql
2、 爲何要移植到.NET Corelinux
.NET Core是.NET Framework的新一代版本,具備跨平臺 (Windows、Mac OSX、Linux) 能力的應用程序開發框架。.NET Core遵循最寬鬆的開源協議,能夠方便的移植到非微軟平臺,同時聽說有至關出色的性能。這些已經足夠吸引人了,對我這一工控狗而言,架構若是限定在Windows操做系統,有幾個問題是難以解決但必須面對的:git
Windows是非實時的操做系統;受限於操做系統,個人網關程序始終找不到高精度的定時器,對一些實時性要求很高的場合,例如高精度機牀控制,就力不從心了,而若是網關能移植到實時系統,這個問題就能獲得解決。github
在一些諸如軍工、機關、央企的場合都指定使用linux操做系統,若是不能跨平臺,顯然根本沒有入局的機會。.NET Core的跨平臺能力保證了普遍的適應性,起碼不會由於綁定平臺而被拒(杯具)。sql
由於寬鬆的開源協議,.NET Core如今已經成爲很熱門的開源項目,在社區得到了普遍的支持。最起碼不用擔憂它的生命被微軟突然宣佈死亡-微軟雖然是.NET社區強有力的支持者,但不是惟一的;有谷歌,三星,Unity甚至紅帽加入的.NET基金會的強大陣容;愈來愈多的開源社區接納了.NET,併爲之開發各類組件和應用。數據庫
看了很多公開資料及社區反饋,.NET Core的性能相比.NET Framework有大幅提高。部分經常使用類庫聽說提高達到60%(求證明)。但.NET Core毫無疑問是.NET 平臺的將來,會獲得持續的升級。安全
3、 如何移植網絡
關於如何移植,博客園有很多好的文章。以我粗淺的理解和實踐,就是創建一個.NET Core項目(VS017支持.NET Core 2.0),VS會自動加載相關的依賴項;將我網關部分的代碼拷貝到新的文件夾下,造成下面這幾個新的基於Core的項目:架構
能夠看到,Core項目沒有常規的dll引用方式,而代之以「項目」引用(即同一解決方案下的項目,這點和.NET Framework相似)以及NuGet包引用。NuGet能夠理解爲類庫「商店」,在NuGet上尋找你須要的組件和類庫,基本上經常使用的,你以爲應該有的,都能搜到,並傻瓜式下載、安裝、部署。
和常規的.NET項目比較,基本大同小異,目標框架可選.NET Core的各版本。編譯後生成的一樣是dll文件,反射依然可用。另外還驚喜的發現.NET Core依然支持不安全代碼-也就是支持指針,彷佛說明微軟設計者至關重視性能問題。
要讓JAVA死忠們接受後來者.NET Core,性能優點、VS支持、部署傻瓜化這些顯然頗有吸引力。對我這類.NET 老用戶而言,一個Core項目並無什麼違和感。一切都是親切的老面孔,但深刻以後,會發現也有一些不一樣之處,只是解決起來整體十分順暢。下面說說我試手將SCADA項目的網關部分初步移植到.NET Core的過程。
4、 .NET Core填坑記
大概的學習了下.NET Core的基本概念,發現有幾個重要問題必需要面對:
沒有UI: Winform、WPF這一類的UI庫並無在.NET Core實現。大概是由於界面這部分各家差別太大,並且界面技術突飛猛進,作跨平臺的界面如今流行用Web。Core只提供了簡單的控制檯輸出顯示。看來人機界面部分(HMI控件、WPF界面)目前是沒法移植了。不過真正有移植價值的仍是在網關部分,這部分若是能跨平臺,界面用H5,WPF,仍是QT都無所謂,反正都是通用的Socket通信。(注:在最新的.NET Core 3.0版本,可以在Windows環境下兼容WPF,Winform,兼容UWP,這個消息值得期待)
沒有對SQL Server的支持:大概由於SQL Server自己就不跨平臺吧。這就逼得我必須尋找一個跨平臺的數據庫用來作系統配置和元數據存儲。根據網友們的建議,我考慮 用MySQL做數據庫,開源跨平臺,用戶多,工具完備,支持網絡訪問,性能也不錯。好在NuGet上有很多開源類庫支持對MySQL讀寫。
在.Net Core下沒有Windows 服務:原有的WCF後臺服務和封裝爲Windows 服務組件的功能廢棄,網關直接掛接一個控制檯程序。須要與客戶端交互,除了原有的基於Socket的TLV協議,還能夠設計RESTful 調用接口,比WCF這種笨傢伙只會更方便。
Windows日誌的實現方式大不相同:大概爲了和其餘系統兼容,不能採用直接讀寫EventLog的方式了。SCADA項目的流水帳記錄和錯誤日誌都寫入Windows事件管理器,必需要替換。我比較了幾種經常使用的日誌移植方法,決定採用微 軟自家的Logging組件,官方支持,同時擴展性看上去不錯,最重要的是簡單,寫法上也和以前區別不大。另外第三方的Log4Net,NLog也移植到了.NET Core,這些日誌庫更爲強大和專業。
沒有內置串口組件:由於是工控組件,對串口的支持是必要的。但Core並無內置SerialPort這種類庫,感受有點奇怪。在NuGet上搜到有RJCP.IO.Ports這個庫,用法和SerialPort大同小異。
還有一些小功能須要移植,如讀寫ini配置文件等。好在NuGet上都有官方類庫可用。
MySQL鏈接用了NuGet下載的MySQLConnector類庫。開源免費,同時下載的人不少,從一個側面印證了它的優秀。我重寫了DataHelper類,使之可以實現多種數據庫支持。簡單起見,套用了一個數據庫工廠模式,定義了一套數據讀寫接口。MySQLConnector比起Framework下的SqlConnector,沒有什麼特別的,繼承的是同一套接口或抽象類,例如DbParameter、DbDataReader、DbCommand等。惟一注意的就是以前慣用的數據庫批量寫入類SqlBulkCopy不能再用了。MySql裏有它自家的批量寫入方式。
對日誌的操做用了一個「提供者模式」,對於在Debug模式下有DebugLoggerProvider、控制檯模式下有ConsoleLoggerProvider,設計十分合理。
對配置文件的管理用了一個構建者(Builder)模式,不管是ini配置方式仍是xml配置方式都有本身的實現。
從對日誌和配置的官方實現,讓我感受微軟對.NET Core的設計頗爲用心。在.NET FX下對配置文件或者日誌的讀寫,要麼是專門對Windows設計的EventLog日誌類,要麼連ini的官方支持都沒有,必須調用API函數。而在Core中進行了重構,進行了合理充分的抽象,架構十分簡潔明瞭,尤爲是充分考慮了各平臺對日誌、配置文件的共性需求,易於擴展,也有助於開源社區自行發展完善。
感受Core和老的Framework仍是很是類似的,起碼絕大部分是兼容的。只有與操做系統和數據庫密切相關的部分被從新實現了,但也很容易在NuGet找到替代辦法。能夠說,移植體驗很順暢。移植過程很傻瓜。讓我這類初次使用者就能很快完成移植,甚至感受Core重寫以後比老的Framework代碼更爲簡潔,架構更爲清晰。這讓我對Core的前景信心大增。
此次的移植只是初試,雖然編譯經過並在虛擬機環境下測試,但並沒在真實Linux環境下測試。由於不熟悉mysql,原有SQL SERVER的部分功能(如存儲過程等)移植不全。將來我但願把網關部分也加入NuGet包,並提供支持.NET Core的設備驅動包下載,依靠開源社區使這個項目支持愈來愈多的系統平臺、硬件設備和行業。
5、 下面的計劃
寫一系列帖子,把架構、原理講清楚。大體以下:
github地址:https://github.com/GavinYellow/SharpSCADA。QQ羣:102486275