Za´padoˇceska´ univerzita v Plzni Fakulta aplikovany´ch vˇed Katedra kybernetiky
Bakal´ aˇ rsk´ a pr´ ace V´ yvoj webov´ eho OPC klienta
Plzeˇ n 2012
Jiˇr´ı Faist
Prohl´ aˇ sen´ı Prohlaˇsuji, ˇze jsem bakal´aˇrskou pr´aci vypracoval samostatnˇe a v´ yhradnˇe s pouˇzit´ım citovan´ ych pramen˚ u. V Plzni dne 23. kvˇetna 2012 Jiˇr´ı Faist
Abstract The goal of this work is to implement an thin client application that would serve for web clients to communicate and manipulate with OPC Servers. In first chapter there are discussed technologies usable for implementation. There are mentioned various approaches to bidirectional communication in web applications with a focus on WebSocket technology. In the next chapter there are exposed some implementation principles along with their advantages and disadvantages. In final chapters there are shown some performance test results of demanding components of application along with the performance statistics of reading various numbers of items from the REX Control OPC server and briefly described example of use of the application with SVG graphic in web browser. C´ılem pr´ace je implementace aplikace typu tenk´eho klienta, kter´a umoˇzn´ı webov´ ym klient˚ um komunikaci a manipulaci s OPC Servery. V prvn´ı ˇc´asti pr´ace jsou diskutov´any technologie, kter´e jsou pouˇziteln´e pro v´ yvoj aplikace. Jsou zde tak´e zm´ınˇeny r˚ uzn´e pˇr´ıstupy k obousmˇern´e komunikaci mezi webov´ ymi klienty a servery se zvl´aˇstn´ım zamˇeˇren´ım na technologii WebSocket. V dalˇs´ı kapitole jsou poodhaleny v´ yznamn´e principy implementace spoleˇcnˇe s jejich v´ yhodami a nev´ yhodami. V z´avˇeru pr´ace jsou uvedeny v´ ysledky mˇeˇren´ı v´ ykonu aplikace se zamˇeˇren´ım na jednotliv´e n´aroˇcn´e komponenty spoleˇcnˇe s v´ ysledky testov´an´ı ˇcten´ı r˚ uzn´eho poˇctu poloˇzek z OPC Serveru ˇr´ıd´ıc´ıho syst´emu REX. V z´avˇeru pr´ace je struˇcnˇe pops´an pˇr´ıklad pouˇzit´ı aplikace s vyuˇzit´ım SVG grafiky ve webov´em prohl´ıˇzeˇci. Key words: opc, opcbridge, webov´ y klient, tenk´ y klient, websocket, rex control
Obsah ´ 1 Uvod
1
2 Pouˇ zit´ e technologie 2.1 Opc Servery a Opc .NET API . . . . . 2.1.1 Standardy OPC . . . . . . . . . 2.1.2 OPC .NET API . . . . . . . . . 2.2 .NET a Reflexe . . . . . . . . . . . . . 2.2.1 .NET Framework . . . . . . . . 2.2.2 Metadata a Reflexe . . . . . . . 2.3 WebSocket . . . . . . . . . . . . . . . . ´ 2.3.1 Uvod do WebSocket technologie 2.3.2 Principy komunikace . . . . . . 2.3.3 WebSocket API . . . . . . . . . 2.4 JSON . . . . . . . . . . . . . . . . . . 2.4.1 Protokol JSON . . . . . . . . . 2.4.2 Pˇr´ıklady JSON form´atu . . . .
. . . . . . . . . . . . .
3 Implementace 3.1 Sch´ema aplikace . . . . . . . . . . . . . . 3.2 Promˇenn´a workspace . . . . . . . . . . . 3.3 Rozhran´ı aplikace . . . . . . . . . . . . . 3.4 Datov´ y form´at JSON a serializace funkc´ı 3.5 Zjednoduˇsen´e API pro pˇr´ıstup k OPC . . 3.6 Zpˇetn´e odezvy a chybov´e hl´aˇsky . . . . . 4 Testov´ an´ı v´ ykonu aplikace 4.1 Reflexe vs. pˇr´ım´ y pˇr´ıstup 4.2 Pˇrenos dat . . . . . . . . 4.3 Serializace a deserializace 4.4 Celkov´ y v´ ykon aplikace .
. . . . . . . . . . objekt˚ u . . . . .
. . . .
. . . .
. . . .
. . . .
. . . . . . . . . . . . .
. . . . . .
. . . .
. . . . . . . . . . . . .
. . . . . .
. . . .
. . . . . . . . . . . . .
. . . . . .
. . . .
. . . . . . . . . . . . .
. . . . . .
. . . .
. . . . . . . . . . . . .
. . . . . .
. . . .
. . . . . . . . . . . . .
. . . . . .
. . . .
. . . . . . . . . . . . .
. . . . . .
. . . .
. . . . . . . . . . . . .
. . . . . .
. . . .
. . . . . . . . . . . . .
. . . . . .
. . . .
. . . . . . . . . . . . .
. . . . . .
. . . .
. . . . . . . . . . . . .
. . . . . .
. . . .
. . . . . . . . . . . . .
2 2 2 3 6 6 6 8 8 10 11 13 13 14
. . . . . .
15 15 16 16 21 24 26
. . . .
27 27 28 28 30
OBSAH
OBSAH
5 Uk´ azka
31
6 Z´ avˇ er
34
4
´ 1 Uvod Z´akladn´ım c´ılem t´eto pr´ace je vytvoˇrit uˇzivatelsky pˇr´atelskou aplikaci, kter´a usnadn´ı pˇr´ıstup k dat˚ um na Opc Serverech(viz. 2.1). Vznikl´a aplikace by mˇela co nejv´ıce odpov´ıdat charakteristik´am aplikace tenk´eho klienta. Tyto aplikace jsou zpravidla spuˇstˇeny na serveru a klient k nim pˇristupuje pomoc´ı snadno dostupn´eho softwarov´eho prostˇredku, typicky webov´eho prohl´ıˇzeˇce. Tento pˇr´ıstup m´a mnoho v´ yhod, z nichˇz nejd˚ uleˇzitˇejˇs´ı je, ˇze veˇsker´a v´ ypoˇcetn´ı z´atˇeˇz je prov´adˇena na serveru a klient je zat´ıˇzen pouze s´ıt’ovou komunikac´ı. Klient tak´e nen´ı nucen instalovat na sv´em poˇc´ıtaˇci ˇza´dn´ y dodateˇcn´ y software. Tato aplikace by mohla naj´ıt vyuˇzit´ı zvl´aˇstˇe pro pˇr´ıstup k dat˚ um ˇr´ıd´ıc´ıho syst´emu REX Controls, kter´ y v sobˇe m´a z´akladn´ı implementaci Opc Serveru. Opc Servery maj´ı definovan´e API1 (rozhran´ı) v .NET Frameworku, pˇres kter´e se k dat˚ um pˇristupuje. Je tedy nasnadˇe toto rozhran´ı vyuˇz´ıt. Z poˇzadavku na tenkost klienta je dalˇs´ım logick´ ym poˇzadavkem, aby rozhran´ı vytvoˇren´e aplikace bylo pˇr´ıstupn´e z programovac´ıho jazyce JavaScript, kter´ y je hlavn´ım programovac´ım jazykem webov´ ych prohl´ıˇzeˇc˚ u. Aplikace tedy bude m´ıt tvar jak´ehosi mostu mezi klientem v JavaScriptu a OPC Serverem, ke kter´emu bude pˇristupov´ano z prostˇred´ı .NET Framework. Z t´eto u ´vahy vypl´ yv´a druh´ y poˇzadavek na aplikaci a t´ım je vytvoˇrit ji natolik obecnˇe, aby mohla b´ yt v budoucnu snadno pˇrizp˚ usobena pro pr´aci i s jin´ ymi rozhran´ımi neˇz je rozhran´ı OPC Server˚ u. V prvn´ı ˇca´sti pr´ace jsou diskutov´any pouˇzit´e technologie, kter´e jsou v implementovan´em ˇreˇsen´ı vyuˇzity. V navazuj´ıc´ıch kapitol´ach se jiˇz nach´azej´ı popis princip˚ u funkce aplikace spoleˇcnˇe s v´ ysledky testov´an´ı aplikace. Souˇca´st´ı pr´ace je tak´e jednoduch´a uk´azka s vizualizac´ı v podobˇe vektorov´e SVG grafiky ve webov´em prohl´ıˇzeˇci, po jej´ımˇz prostudov´an´ı by mˇel b´ yt ˇcten´aˇr schopen aplikaci aktivnˇe vyuˇz´ıvat.
1
API - Application Programming Interface
1
2 Pouˇzit´e technologie 2.1 2.1.1
Opc Servery a Opc .NET API Standardy OPC
OPC je soubor specifikac´ı, kter´e popisuj´ı standardy naplˇ nuj´ıc´ı specifick´e potˇreby pr˚ umyslu. O udrˇzov´an´ı tˇechto otevˇren´ ych standard˚ u se star´a na1 dace OPC Foundation. Prvn´ı standart OPC Data Access vznikl na z´akladˇe spolupr´ace mnoha svˇetov´ ych podnik˚ u, zajiˇst’uj´ıc´ıch automatizaci, za pomoci Microsoftu. Tato specifikace je p˚ uvodnˇe postaven´a na technologi´ıch Micro2 3 softu OLE COM a DCOM . Tyto technologie umoˇzn ˇuj´ı softwarov´ ym komponent´am vz´ajemnou komunikaci a jsou vyuˇz´ıv´any v´ yvoj´aˇri pro vytv´aˇren´ı znovupouˇziteln´ ych komponent, slinkov´an´ı komponent dohromady a vyuˇz´ıv´an´ı v´ yhod Windows servis˚ u[Mic(2012a)]. Specifikace definuje z´akladn´ı set objekt˚ u, rozhran´ı a metod pro pouˇzit´ı pˇri ˇr´ızen´ı proces˚ u a automatizaci tak, aby zajistila vz´ajemnou kompatibilitu[OPC(2012)]. OPC aplikace jsou implementov´any jako dvojice server/klient. OPC server je program, kter´ y konvertuje hardwarov´ y komunikaˇcn´ı protokol pouˇz´ıvan´ y v PLC4 na OPC protokol[Cog(1995-2010)]. OPC klient je program, kter´ y se potˇrebuje pˇripojit k hardwarov´emu zaˇr´ızen´ı. Pouˇz´ıv´a OPC server pro z´ısk´an´ı dat ze zaˇr´ızen´ı nebo pro vysl´an´ı pˇr´ıkazu do zaˇr´ızen´ı (viz. obr. 2.1). K d˚ uleˇzit´ ym vlastnostem OPC patˇr´ı to, ˇze se jedn´a o otevˇren´ y standard, z ˇcehoˇz vypl´ yv´a, ˇze v´ yrobce hardwaru mus´ı poskytnout jedin´ y OPC server pro sv´a zaˇr´ızen´ı, aby mohla komunikovat s kter´ ymkoliv klientem. Z opaˇcn´eho pohledu je patrn´e, ˇze rovnˇeˇz v´ yvoj´aˇr˚ um aplikac´ı staˇc´ı zan´est do sv´eho produktu vlastnosti OPC klienta a t´ım budou kompatibiln´ı s mnoha hardwarov´ ymi zaˇr´ızen´ımi. 1
p˚ uvodnˇe naz´ yvan´ y OPC Specification OLE- Object Linking and Embedding; COM - component object model 3 distributed component object model 4 Programmable Logic Controller - mal´ y pr˚ umyslov´ y poˇc´ıtaˇc kontroluj´ıc´ı jedno ˇci v´ıce hardwarov´ ych zaˇr´ızen´ı 2
2
Pouˇzit´e technologie
Opc Servery a Opc .NET API
Windows
Hardware
PLC
OPC Server
OPC Client Software
Obr´azek 2.1: jednoduch´e OPC s jedn´ım server/klient pˇripojen´ım
2.1.2
OPC .NET API
OPC .NET(WCF5 )6 je API pro pˇr´ıstup k OPC server˚ um z prostˇred´ı Microsoft .NET Frameworku. OPC .NET 3.0 je v´ ysledkem spolupr´ace nˇekolika spoleˇcnost´ı, kter´ y poskytuje jednoduch´e .NET rozhran´ı pro OPC Classic servery. Bylo vyvinuto tak, aby umoˇznilo klientsk´ ym aplikac´ım vyuˇz´ıvat pˇrednosti .NET prostˇred´ı pˇri pˇristupov´an´ı k existuj´ıc´ım OPC Classic server˚ um [OPC(2012)]. Rozhran´ı OPC .NET 3.0 kombinuje s´emantiku z´akladn´ıch OPC specifikac´ı OPC Data Access, OPC Alarms and Events a OPC Historical Data Access 7 . Rozhran´ı tak´e umoˇzn ˇuje automatick´e znovupˇripojen´ı k serveru, jestliˇze dojde ke ztr´atˇe spojen´ı. Tato vlastnost rovnˇeˇz zachov´av´a na serveru povˇedom´ı o klientu, takˇze klient nemus´ı znovu vytv´aˇret sv´e nastaven´ı na serveru. OPC .NET 3.0 API je navrˇzeno tak, aby klientsk´a aplikace byla oddˇelena od s´ıt’ov´eho rozhran´ı. Klientsk´a aplikace uˇz se nemus´ı vypoˇr´ad´avat s vˇecmi kolem s´ıt’ov´eho pˇripojen´ı jako napˇr´ıklad s v´ ymˇenami poˇzadavk˚ u a odezev(request/response). Tyto u ´kony obstar´av´a zdrojov´ y k´od, kter´ y je distribuov´an s API, a WCF rozhran´ı. OPC .NET je distribuov´ano se tˇremi generick´ ymi klientsk´ ymi aplikacemi, kter´e byly vytvoˇreny jako model pro v´ yvoj klientsk´ ych aplikac´ı a slouˇz´ı tak´e pro testov´an´ı novˇe vyvinut´ ych server˚ u pro ovˇeˇren´ı spr´avn´e funkˇcnosti. Na stranˇe serveru je pˇr´ıtomn´ y generick´ y wrapper pro OPC DA, A&E 5
Windows Communication Foundation - souˇc´ast .NET Framework urˇcen´a pro tvorbu servisovˇe orientovan´ ych aplikac´ı 6 dˇr´ıve naz´ yvan´e OPC Express Interface (Xi) 7 d´ ale pouˇz´ıv´ ano ve zkratk´ ach DA, A&E, HDA
3
Pouˇzit´e technologie
Opc Servery a Opc .NET API
nebo HDA servery. Wrapper je rozdˇelen do dvou ˇc´ast´ı, prvn´ı obstar´av´a WCF rozhran´ı a druh´a se star´a o mapov´an´ı mezi OPC .NET a OPC Classic funkcemi (viz. obr.2.2). Zdrojov´ y k´od, kter´ y zajiˇst’uje WCF rozhran´ı serveru je oznaˇcen jako b´aze serveru. Tato ˇca´st definuje stejn´e chov´an´ı vˇsech OPC .NET server˚ u a je tedy vˇzdy stejn´a. Pro vyhled´av´an´ı pˇr´ıpustn´ ych server˚ u obsahuje OPC .NET Discovery server, kter´ y vytv´aˇr´ı seznam server˚ u dostupn´ ych pro klientskou aplikaci. K tomu vyuˇz´ıv´a technologii Microsoft Peer Name Resolution Protocol (PNRP), kter´a je dostupn´a na syst´emech Windows XP a vyˇsˇs´ıch. Klientská API
Rozhraní WCF
Standardní Wrapper
Generický Klient
Klientská báze
Class API Klient
OPC COM Server
Báze Serveru
Class API Adhoc Klient
OPC Wrapper
WCF
alternativní implementace .NET serveru
Adhoc API
Standardní kód klienta
Standardní kód serveru
Specifický kód vývojáře
Obr´azek 2.2: OPC .NET klient a server
Funkˇ cn´ı architektura Na obr´azku 2.3 jsou pˇribl´ıˇzeny principy funkce vztahu OPC server/klient. Z´akladem jsou jak´esi pˇr´ıstupov´e body serveru definovan´e rozhran´ımi Spraˇ vuj(Manage), Cti(Read), Zapiˇs(Write) a Pˇrihlaˇs se k odbˇeru(Subscribe). Kaˇzd´ y klient si vytv´aˇr´ı vlastn´ı seznamy ze zdroj˚ u v syst´emu. Ty jsou pro vˇsechny klienty stejn´e na rozd´ıl od vznikl´ ych seznam˚ u, kter´e m´a kaˇzd´ y klient vlastn´ı. Klient pot´e tyto seznamy m˚ uˇze pˇriˇradit k pˇr´ıstupov´ ym bod˚ um. Kaˇzd´ y klient m˚ uˇze m´ıt v´ıce pˇr´ıstupov´ ych bod˚ u a ke kaˇzd´emu pˇr´ıstupov´emu bodu m˚ uˇze b´ yt pˇriˇrazeno v´ıce seznam˚ u[Neitzel(2009)]. Server tedy disponuje n´asleduj´ıc´ımi rozhran´ımi: • ServerDiscovery - pouˇz´ıvan´e pro nalezen´ı server˚ u 4
Pouˇzit´e technologie
Opc Servery a Opc .NET API
Zdroje v systému stejné pro všechny klienty
Spravuj
filter filter
Klientská aplikace
Runtime data
Historická data
Alarms &Events
Historical Alarms &Events
Čti Zapiš Odebírej Oblast specifická pro každého klienta
Obr´azek 2.3: Sch´ema funkˇcn´ı architektury OPC .NET • ResourceManagement - umoˇzn ˇuje prohled´av´an´ı zdroj˚ u serveru, vytv´aˇren´ı seznam˚ u z tˇechto zdroj˚ u, vytv´aˇren´ı pˇr´ıstupov´ ych bod˚ u a pˇridˇelov´an´ı seznam˚ u pˇr´ıstupov´ ym bod˚ um • Subscribe pˇr´ıstupov´e body mohou b´ yt dva typy urˇcen´e hlavnˇe druhem pouˇzit´eho protokolu: – Callback - urˇcen´e pro pˇr´ıstup k dat˚ um v r´amci jednoho stroje pˇr´ıpadnˇe m´ıstn´ı s´ıtˇe, protokol TCP – Poll - urˇcen´e pro pˇr´ıstup z internetu, webov´ ych aplikac´ı atd., protokol HTTP • Read - obsahuje metody pro ˇcten´ı hodnot ze serveru • Write - obsahuje metody pro zmˇenu stavu serveru a pro z´apis hodnot na server
5
Pouˇzit´e technologie
2.2
.NET a Reflexe
2.2.1
.NET Framework
.NET a Reflexe
.NET Framework8 je technologie vyvinut´a spoleˇcnost´ı Microsoft. Podporuje ˇradu programovac´ıch jazyk˚ u a snaˇz´ı se mezi nimi zajistit vz´ajemnou interoperabilitu. Pˇri kompilaci v .NET se zdrojov´ y k´od programu pˇrekl´ad´a do Common Intermediate Language(CIL), coˇz je nejniˇzˇs´ı pro ˇclovˇeka ˇciteln´ y programovac´ı jazyk. Do bin´arn´ıho k´odu je program v CIL pˇreloˇzen aˇz za bˇehu. CIL je ukl´ad´an do assembly, kter´a je bud’ ve tvaru spustiteln´eho souboru .exe nebo ve tvaru .dll 9 . Kromˇe CIL k´odu assembly jeˇstˇe obsahuje sv˚ uj Manifest, Metadata a Reference.
2.2.2
Metadata a Reflexe
Kaˇzd´a assembly obsahuje sv´a Metadata, kter´a jsou tvoˇrena automaticky pˇri pˇrekladu. Metadata popisuj´ı kaˇzd´ y datov´ y typ a ˇclen, kter´ y je v modulu nebo v assembly definov´an nebo je na nˇej odkazov´ano a jsou z´akladem pro reflexi v .NET Frameworku. Reflexe v programov´an´ı je proces, pˇri kter´em je dan´ y program schopn´ y za bˇehu sledovat a modifikovat svou vlastn´ı strukturu a chov´an´ı[Hurlbut(1998)]. V .NET zajiˇst’uje reflexi jmenn´ y prostor System.Reflection, jehoˇz objekty zaobaluj´ı assembly, moduly a datov´e typy. Tyto objekty mohou b´ yt vyuˇzity k dynamick´emu vytv´aˇren´ı instanc´ı objekt˚ u, z´ısk´av´an´ı informace o typu existuj´ıc´ıho objektu, vyvol´av´an´ı jeho metod nebo k pˇr´ıstupu k jeho poloˇzk´am a vlastnostem[Mic(2012b)]. Jedin´e co mus´ı uˇzivatel pro pouˇzit´ı reflexe zn´at je jm´eno datov´eho typu objektu a informace o assembly, ve kter´e je objekt definov´an. V .NET reflexe funguje na z´akladˇe parsov´an´ı v´ yˇse zmiˇ novan´ ych Metadat z assembly.
Pˇri v´ yvoji aplikace se nab´ızeli dva r˚ uzn´e zp˚ usoby implementace. Prvn´ı moˇznost´ı bylo cel´e (a nebo znaˇcnou ˇca´st) OPC .NET API pˇr´ımo zpˇr´ıstupnit v klientu JavaScriptu. V JavaScriptu by tedy musel b´ yt obraz kaˇzd´eho objektu a kaˇzd´e metody, kter´e jsou definovan´e v OPC .NET API. Vzhledem 8
framework - podp˚ urn´ y prostˇredek pro program´atora obsahuj´ıc´ı v´ yvojov´e prostˇred´ı, podp˚ urn´e knihovny atd. 9 Dynamic Link Library
6
Pouˇzit´e technologie
.NET a Reflexe
k velikosti API se to ale jev´ı jako znaˇcnˇe nevhodn´e ˇreˇsen´ı, nebot’ rozhran´ı aplikace v JavaScriptu by muselo b´ yt rozs´ahl´e a komplikovan´e. Jako druh´e ˇreˇsen´ı se nab´ız´ı vytvoˇrit ˇca´st aplikace, kter´a v prostˇred´ı .NET manipuluje s OPC .NET API za vyuˇzit´ı reflexe. Hlavn´ı v´ yhodou tohoto ˇreˇsen´ı je moˇznost velice jednoduˇse vymˇenit API, ke kter´emu se klient pˇripojuje. Toto ˇreˇsen´ı dokonce umoˇzn ˇuje pˇripojovat se k nˇekolika API nez´avisle na sobˇe. JavaScriptov´a ˇc´ast nav´ıc mus´ı v z´akladn´ı verzi obsahovat pouze obecn´e metody pro vytvoˇren´ı objektu, zavol´an´ı metody nad objektem a nastaven´ı ˇclenu objektu na urˇcitou hodnotu. Na druhou stranu zde existuj´ı i nev´ yhody. Nejz´avaˇznˇejˇs´ı z nich je skuteˇcnost, ˇze pˇreˇcten´ı hodnoty nˇejak´eho ˇclenu objektu pˇres reflexi nebo vyvol´an´ı metody objektu pouˇzit´ım reflexe je mnohem pomalejˇs´ı neˇz pˇri pˇr´ım´em pˇr´ıstupu (viz. sekce 4.1). Dalˇs´ı nev´ yhodou jsou vˇetˇs´ı pamˇet’ov´e n´aroky, protoˇze do pamˇeti se mus´ı naˇc´ıst mnoˇzstv´ı Metadat o vyuˇz´ıvan´ ych objektech.
7
Pouˇzit´e technologie
2.3
WebSocket
WebSocket ´ Uvod do WebSocket technologie
2.3.1
Navrhovanou aplikace si lze pˇredstavit jako most mezi JavaScriptem a OPC Serverem. K OPC Serveru se pˇristupuje pˇres rozhran´ı definovan´e v .NET. Data mezi prostˇred´ımi jazyka JavaScriptu a .NET jsou pˇren´aˇsena pˇres WebSocket server. WebSocket je protokol, kter´ y umoˇzn ˇuje obousmˇernou komunikaci mezi klientsk´ ym skriptem a vzd´alen´ ym serverem, kter´ y byl v tomto skriptu zvolen [Ian Fette(2011)]. Klientem jsou ve vˇetˇsinˇe pˇr´ıpad˚ u webov´e prohl´ıˇzeˇce s podporou HTML5. Z´akladn´ı architektura je nast´ınˇena na obr´azku 2.4. Protokol se skl´ad´a z otev´ırac´ıho ”handshake”, po kter´em zpravidla n´asleduje v´ y10 mˇena informac´ı zaloˇzen´a na z´akladˇe komunikaˇcn´ıho protokolu TCP . C´ılem t´eto technologie je poskytnout mechanismus pro webov´e aplikace komunikuj´ıc´ı obousmˇernˇe se servery, kter´ y nebude z´avisl´ y na otev´ır´an´ı velk´eho poˇctu HTTP pˇripojen´ı.
Trading Gateway
Platební systém
Databáze
Internet Web Service
Messaging Service
ERP/CRM Systémy
atd...
Webové prohlížeče
WebSocket Server
Obr´azek 2.4: Z´akladn´ı architektura technologie Websocket
10
Transmission Control Protocol
8
Pouˇzit´e technologie
WebSocket
Alternativn´ı metody obousmˇ ern´ e s´ıt’ov´ e komunikace WebSocket by mˇel poskytnout n´ahradu za doposud pouˇz´ıvan´e technologie HTTP polling, long-polling a streaming. Vˇsechny tyto metody zahrnuj´ı pos´ıl´an´ı HTTP poloˇzek (headers), kter´e obsahuj´ı mnoho zbyteˇcn´ ych dat, ˇc´ımˇz doch´az´ı ke zv´ yˇsen´ı latence nad minim´aln´ı u ´roveˇ n. WebSocket je navrˇzen tak, aby mohl zuˇzitkovat existuj´ıc´ı infrastrukturu (proxy servery, ovˇeˇrov´an´ı, atd.)
polling Pˇri pollingu klient v pravideln´ ych intervalech pos´ıl´a serveru HTTP poˇzadavky a okamˇzitˇe pˇrij´ım´a odpovˇed’. Tato technika je pouˇz´ıv´ana pro zisk dat z real-time aplikac´ı. Poskytuje dobr´e ˇreˇsen´ı, pokud je zn´am´ y interval, po jehoˇz uplynut´ı jsou na serveru poskytov´ana nov´a data. Bohuˇzel tento interval je ˇcasto nepravideln´ y a nepˇredv´ıdateln´ y. Proto doch´az´ı k otev´ır´an´ı zbyteˇcn´ ych HTTP pˇripojen´ı, obzvl´aˇstˇe pokud nov´e informace nejsou dostupn´e pˇr´ıliˇs ˇcasto.
long-polling Pˇri long-pollingu prohl´ıˇzeˇc pos´ıl´a serveru poˇzadavek a ten ho nech´a otevˇren´ y tak dlouho, neˇz bude m´ıt pro klienta nˇejak´a data. Pokud se tak ve zvolen´em vymezen´em ˇcase nestane, server poˇsle odpovˇed’ pro ukonˇcen´ı pˇripojen´ı. Z principu long-polling vypl´ yv´a, ˇze nepˇrin´aˇs´ı ˇza´dn´e zlepˇsen´ı v˚ uˇci polling v pˇr´ıpadˇe, ˇze se data na serveru ˇcasto obnovuj´ı.
streaming Dalˇs´ı z moˇzn´ ych pˇr´ıstup˚ u je streaming, pˇri kter´em prohl´ıˇzeˇc poˇsle serveru poˇzadavek a server mu jako odpovˇed’ pr˚ ubˇeˇznˇe pos´ıl´a data. Nemus´ı tedy ˇcekat na vygenerov´an´ı kompletn´ı odpovˇedi, aby ji mohl poslat najednou. Streaming nesniˇzuje latenci pˇripojen´ı, jeho v´ yhodou ale je, ˇze klient m˚ uˇze na pˇr´ıchoz´ı data reagovat uˇz v pr˚ ubˇehu pˇrij´ım´an´ı dat. Streaming je ale st´ale zaloˇzen´ y na technologii HTTP, coˇz m˚ uˇze zp˚ usobit, ˇze firewally a proxy servery si mohou zvolit, ˇze budou data bufferovat, coˇz zp˚ usob´ı zv´ yˇsen´ı latence doruˇcen´ı zpr´avy. Nav´ıc server je nucen pouˇz´ıvat nˇekolik r˚ uzn´ ych TCP pˇripojen´ı pro kaˇzd´eho klienta: jeden pro pos´ıl´an´ı informac´ı a dalˇs´ı pro kaˇzdou novˇe pˇr´ıchoz´ı zpr´avu. WebSocket oproti tomu umoˇzn ˇuje pro komunikaci v obou smˇerech vyuˇz´ıt pouze jedno TCP pˇripojen´ı [web(2011)].
9
Pouˇzit´e technologie
2.3.2
WebSocket
Principy komunikace
Handshake Term´ın handshake v komunikaˇcn´ıch technologi´ıch oznaˇcuje proces, pˇri kter´em mezi u ´ˇcastn´ıky komunikace doch´az´ı k dohodnut´ı se na hodnot´ach dynamick´ ych parametr˚ u pˇred vlastn´ım zapoˇcet´ım komunikace. Moˇzn´a podoba handshake klienta a serveru pro technologii WebSocket je uvedena v Pˇr´ıloze 1. Handshake v protokolu WebSocket m´a tvar HTTP Upgrade poˇzadavku. D´ıky tomu je tato technologie kompatibiln´ı s HTTP servery a s prostˇredn´ıky na HTTP b´azi. Dalˇs´ım d˚ usledkem je moˇznost vyuˇzit´ı jednoho portu pro HTTP i WebSocket klienty. Klient ve sv´em handshake specifikuje poˇzadovanou adresu URI11 , ke kter´e se chce pˇripojit. Tento zp˚ usob umoˇzn ˇuje, aby z jedn´e IP adresy mohlo b´ yt obslouˇzeno v´ıce dom´en a aby v´ıce WebSocket klient˚ u mohlo b´ yt obslouˇzeno jedin´ ym serverem[Ian Fette(2011)]. Pro URI Websocketu jsou definov´ana dvˇe sch´emata. Pro klasick´e Websocket pˇripojen´ı m´a URI prefix ws:// a pro zabezpeˇcenou verzi se pouˇz´ıv´a prefix wss://. Kromˇe poˇzadovan´e URI klientsk´ y handshake obsahuje i dalˇs´ı poloˇzky pro upˇresnˇen´ı zp˚ usobu n´asledn´e komunikace. • Sec-WebSocket-Protocol - urˇcen´ı aplikaˇcn´ıho protokolu, kter´ y znaˇc´ı form´at, v jak´em budou data pˇren´aˇsena • Sec-WebSocket-Extensions - seznam ˇza´dan´ ych rozˇs´ıˇren´ı protokolu(napˇr. komprese dat atd.) • Origin - poloˇzka slouˇz´ıc´ı k filtrov´an´ı webov´ ych str´anek, ze kter´ ych m´a b´ yt server pˇr´ıstupn´ y • Sec-WebSocket-Version - verze protokolu Po odesl´an´ı sv´eho handshake klient mus´ı poˇckat na odpov´ıdaj´ıc´ı handshake serveru, dˇr´ıve neˇz zaˇcne pos´ılat dalˇs´ı data. Server si z klientova handshake mus´ı vyjmout poloˇzku Sec-WebSocketKey v n´ıˇz se nach´az´ı n´ahodn´ y klientem vybran´ y ˇretˇezec a uprav´ı ho podle stanoven´ ych pravidel. Tak z´ısk´a ˇretˇezec, kter´ y pot´e odeˇsle ve sv´em handshake v poloˇzce Sec-WebSocket-Accept. T´ımto zp˚ usobem si klient ovˇeˇruje, ˇze pˇrijat´ y handshake poch´az´ı od j´ım zvolen´eho serveru. Jakmile klient pˇrijme handshake serveru, mohou si obˇe strany komunikaˇcn´ıho kan´alu nez´avisle na sobˇe pos´ılat data. 11
Uniform Resource Identifier
10
Pouˇzit´e technologie
WebSocket
Data Framing Po u ´spˇeˇsn´em handshake si mohou klient se serverem vymˇen ˇovat data. Tato data jsou sdruˇzov´ana do celk˚ u oznaˇcovan´ ych jako ”messages”, kter´e jsou d´ale rozdˇelen´e do jednotliv´ ych r´amc˚ u neboli fram˚ u. V Pˇr´ıloze 2 je zobrazen z´akladn´ı tvar pro jeden r´amec. Vysvˇetlen´ı jednotliv´ ych ˇca´st´ı r´amce je v Pˇr´ıloze 3. Hlavn´ı v´ yhoda fragmentov´an´ı zpr´av spoˇc´ıv´a v tom, ˇze server m˚ uˇze zaˇc´ıt pos´ılat fragmenty zpr´avy jeˇstˇe pˇred t´ım, neˇz m´a celou zpr´avu k dispozici. Pokud by zpr´ava nebyla fragmentov´ana, odes´ılatel by musel poˇckat aˇz bude m´ıt celou zpr´avu a spoˇc´ıtat jej´ı velikost dˇr´ıve, neˇz by mohl b´ yt odesl´an prvn´ı byte. D´ıky fragmentaci m˚ uˇze server nebo prostˇredn´ık zvolit rozumnou velikost bufferu a jakmile se buffer napln´ı r´amec odeslat.
Ukonˇ cen´ı spojen´ı Po u ´spˇeˇsn´em otev´ırac´ım handshake a pˇrenosu potˇrebn´ ych dat spojen´ı ukonˇcuje uzav´ırac´ı handshake. Kter´ ykoliv z koncov´ ych bod˚ u m˚ uˇze vyvolat uzav´ırac´ı handshake t´ım, ˇze odeˇsle sv´emu protˇejˇsku uzav´ırac´ı r´amec, jehoˇz tvar lze odvodit z Pˇr´ılohy 3. Po odesl´an´ı tohoto r´amce jiˇz nesm´ı pokraˇcovat v odes´ıl´an´ı ˇz´adn´ ych dat a vyˇck´av´a na odezvu tak´e v podobnˇe uzav´ırac´ıho r´amce. Po pˇrijet´ı odpovˇedi inici´ator ukonˇcen´ı komunikace ukonˇc´ı spojen´ı.
2.3.3
WebSocket API
HTML5 WebSocket specifikace definuje jednoduch´e API, kter´e umoˇzn ˇuje webov´ ym str´ank´am pouˇz´ıt WebSocket protokol pro komunikaci se vzd´alen´ ym hostitelem. Kompletn´ı podoba rozhran´ı v s´emantice WebIDL12 lze naj´ıt v Pˇr´ıloze 4.
Konstruktor Konstruktor WebSocket(url, protocols) m´a jeden nebo dva argumenty. Prvn´ı z nich, url, urˇcuje URL adresu, ke kter´e se m´a WebSocket pˇripojit. Parametr protocols je nepovinn´ y a je typu string nebo pole string˚ u. Tyto ˇretˇezce maj´ı v´ yznam subprotokol˚ u a jsou obsaˇzeny v klientsk´em handshake v poloˇzce Sec-WebSocket-Protocol [Hickson(2012)]. ´ Ukolem konstruktoru je na z´akladˇe pˇredan´ ych parametr˚ u vytvoˇrit nov´e pˇripojen´ı k serveru a vr´atit nov´ y WebSocket objekt. 12
WebIDL - jazyk zamˇeˇren´ y na popis rozhran´ı technologi´ı urˇcen´ ych pro webov´e prohl´ı-
ˇzeˇce
11
Pouˇzit´e technologie
WebSocket
Atribut readyState c´ıch hodnot:
reprezentuje stav spojen´ı a m˚ uˇze nab´ıvat n´asleduj´ı-
• CONNECTING(ˇc´ıseln´a hodnota 0) - pˇripojen´ı jeˇstˇe nebylo vytvoˇreno • OPEN(ˇc´ıseln´a hodnota 1) - pˇripojen´ı je vytvoˇreno a pos´ıl´an´ı dat je moˇzn´e • CLOSING(ˇc´ıseln´a hodnota 2) - pˇripojen´ı je ve stavu prob´ıhaj´ıc´ıho closing handshake • CLOSED(ˇc´ıseln´a hodnota 3) - pˇripojen´ı je uzavˇren´e a nebo nemohlo b´ yt otevˇreno
Atribut bufferedAmount Atribut bufferedAmount obsahuje poˇcet byt˚ u, kter´e byly pˇrid´any do fronty pouˇzit´ım metody send a nebyly jeˇstˇe odesl´any.
Metoda send(data) n´eho pˇripojen´ı.
Tato metoda pos´ıl´a data prostˇrednictv´ım vytvoˇre-
Metoda close() Tato metoda spouˇst´ı proceduru uzav´ırac´ıho handshake a ukonˇcuje spojen´ı se serverem. Voliteln´ ym parametrem je integer s k´odem chyby, kter´a zp˚ usobila ukonˇcen´ı spojen´ı. V n´asleduj´ıc´ı tabulce jsou event handlery13 , kter´e obsahuje WebSocket rozhran´ı. Tyto handlery jsou zpravidla pˇrepisov´any uˇzivatelem, kter´ y rozhran´ı vyuˇz´ıv´a. Event handler onopen() onmessage() onerror() onclose()
13
ud´alost, pˇri kter´e je handler spuˇstˇen u ´spˇeˇsn´e vytvoˇren´ı pˇripojen´ı pˇrijet´ı nov´e zpr´avy pˇr´ıjet´ı r´amce s chybov´ ym hl´aˇsen´ım pˇrijet´ı uzav´ırac´ıho r´amce
metody pro zpracov´ an´ı vznikl´ ych asynchronn´ıch ud´alost´ı
12
Pouˇzit´e technologie
2.4
JSON
JSON
V sekci 2.3 je pops´ana technologie WebSocket vyuˇz´ıvan´a pro pˇrenos dat ve tvaru textov´ ych ˇretˇezc˚ u. Ve smˇeru od prohl´ıˇzeˇce tyto ˇretˇezce obsahuj´ı jen jednoduch´e pˇr´ıkazy pro OPC .NET API. V opaˇcn´em smˇeru je ale nutn´e pos´ılat data reprezentuj´ıc´ı v´ ysledky vykon´an´ı tˇechto pˇr´ıkaz˚ u. Pro reprezentaci tˇechto dat byl vybr´an protokol JSON.
2.4.1
Protokol JSON
JSON (JavaScript Object Notation) je odlehˇcen´ y form´at pro v´ ymˇenu ” 14 dat a serializaci objekt˚ u . Je jednoduˇse ˇciteln´ y i zapisovateln´ y ˇclovˇekem a snadno analyzovateln´ y i generovateln´ y strojovˇe“ [jso()]. JSON je vytvoˇren na z´akladech jednoho z moˇzn´ ych zp˚ usobu vytv´aˇren´ı objekt˚ u v programovac´ım jazyce JavaScript. J e textov´ y form´at, kter´ y, pˇrestoˇze vych´az´ı z JavaScriptu, je na pouˇzit´em jazyce zcela nez´avisl´ y.
JSON podporuje dvˇe struktury: • Struktura reprezentuj´ıc´ı objekt. Objekt je br´an jako mnoˇzina p´ar˚ u obsahuj´ıc´ı n´azev ˇclenu objektu a jeho hodnoty. Pˇri deserializaci objekt˚ u v JSON form´atu do jin´ ych jazyk˚ u neˇz JavaScriptu se obvykle vyuˇz´ıvaj´ı struktury typu objekt, z´aznam, struktura, slovn´ık, hash tabulka a dalˇs´ı. • Struktura reprezentuj´ıc´ı pole. Obˇe struktury se vyskytuj´ı v nˇejak´e formˇe v podstatˇe ve vˇsech programovac´ıch jazyc´ıch a proto je JSON podporovan´ y vˇetˇsinou programovac´ıch jazyk˚ u a znaˇcnˇe rozˇs´ıˇren´ y. Kromˇe tˇechto struktur se v JSON mohou objevit jeˇstˇe textov´e ˇretˇezce, ˇc´ıseln´e hodnoty, hodnoty boolean a hodnota null.
14
serializace objektu - zpracov´ an´ı a uloˇzen´ı instance do perzistentn´ıho uloˇziˇstˇe
13
Pouˇzit´e technologie
2.4.2
JSON
Pˇ r´ıklady JSON form´ atu
• Pˇr´ıklad z´apisu jednoduch´eho pole ˇc´ıseln´ ych hodnot [ 10, 5, 98, 20, 30 ] • Pˇr´ıklad z´apisu jednoduch´eho objektu { color: "red", value: "#f00" array: [ 10, 5, 98, 20, 30 ] } • Pˇr´ıklad z´apisu pole objekt˚ u [ { color: "red", value: "#f00" }, { color: "green", value: "#0f0" }, { color: "blue", value: "#00f" } ]
14
3 Implementace 3.1
Sch´ ema aplikace
Aplikace funguje jako most propojuj´ıc´ı klienta v JavaScriptu a prostˇred´ı OPC Server˚ u, ke kter´ ym se pˇristupuje prostˇrednictv´ım OPC .NET API. Mezi JavaScriptem a OPC Servery tedy mus´ı existovat meziˇcl´anek v .NET, kter´ y bude zpracov´avat pˇr´ıkazy z JavaScriptu a podle nich manipulovat s rozhran´ım OPC server˚ u. Z podporovan´ ych programovac´ıch jazyk˚ u prostˇred´ı .NET byl vybr´an C#, kter´ y byl vytvoˇren spoleˇcnost´ı Microsoft pr´avˇe pro u ´ˇcely .NET Frameworku. Na obr´azku 3.1 je nast´ınˇeno z´akladn´ı sch´ema aplikace. V JavaScriptu je vytvoˇren objekt s urˇcit´ ym rozhran´ım, kter´e d´ale vyuˇz´ıv´a klient z webov´eho prohl´ıˇzeˇce. Hlavn´ım u ´kolem tohoto objektu je pos´ılat zpr´avy s pˇr´ıkazy prostˇrednictv´ım WebSocket serveru do prostˇred´ı .NET, kde jsou tyto pˇr´ıkazy vykon´any. Rozhran´ı v JavaScriptu a v .NET jsou stejn´a, protoˇze ke kaˇzd´emu pˇr´ıkazu je v JavaScriptu metoda , kter´a tento pˇr´ıkaz odeˇsle, a v .NET metoda, kter´a tento pˇr´ıkaz vykon´a. Pˇr´ıkazy obsahuj´ı pokyny pro manipulaci s OPC .NET API, kter´a prob´ıh´a dynamicky na z´akladˇe reflexe (viz. sekce 2.2.2).
Klientská aplikace ve webovém prohlížeči
AddToWorkspace()
AddToWorkspace()
Invoke()
Invoke()
SetValue()
SetValue()
Refresh()
Refresh()
Remove()
Remove()
workspace
workspace .NET (C#)
JavaScript WebSocket Server
Obr´azek 3.1: Sch´ema aplikace.
15
Reflexe
OPC .NET API
Implementace
3.2
Promˇenn´a workspace
Promˇ enn´ a workspace
Jak jiˇz bylo ˇreˇceno, aplikace m´a podobu pomysln´eho mostu mezi klientem v JavaScriptu a OPC .NET API, se kter´ ym manipuluje jak´ ysi meziˇcl´anek implementovan´ y v jazyce C#. Z´akladem funkce aplikace je promˇenn´a workspace, kter´a se nach´az´ı v JavaScriptov´e ˇca´sti a v ˇca´sti aplikace implementovan´e v C#(viz. obr.3.1). Na stranˇe JavaScriptu se jedn´a o datov´ y typ objekt. Objekty v JavaScriptu jsou v podstatˇe mnoˇziny p´ar˚ u kl´ıˇc|hodnota, kde kl´ıˇce jsou ˇretˇezce a hodnota m˚ uˇze b´ yt jak´ ykoliv datov´ y typ. Na stranˇe C# je tato struktura reprezentov´ana slovn´ıkem Dictionary<string,object> ze jmenn´eho prostoru System.Collections.Generic. Kl´ıˇce v tomto slovn´ıku jsou rovnˇeˇz ˇretˇezce a hodnotami, kter´e odpov´ıdaj´ı kl´ıˇc˚ um, mohou b´ yt libovoln´e objekty. V promˇenn´e workspace se uchov´avaj´ı veˇsker´e uˇzivatelem vytv´aˇren´e objekty. Uˇzivatel v JavaScriptu zavol´a metodu pro vytvoˇren´ı objektu, ten se na stranˇe C# vytvoˇr´ı, uloˇz´ı se do promˇenn´e workspace v C# a zpˇetnˇe se zrcadl´ı do promˇenn´e workspace na stranˇe JavaScriptu. Nav´ıc se ke kaˇzd´emu objektu ve workspace v JavaScriptu pˇrid´av´a poloˇzka dotnettype, kter´a obsahuje ˇretˇezec s datov´ ym typem, jenˇz odpov´ıd´a typu objektu v C#, podle kter´eho tento obraz vznikl. Tato poloˇzka je zavedena z d˚ uvodu absence typov´e kontroly v JavaScriptu pˇri vol´an´ı metod (v´ıce o vol´an´ı metod pozdˇeji v sekci 3.4). Zrcadlen´ı objekt˚ u prob´ıh´a v´ ymˇennou dat ve form´atu JSON(viz. 2.4) pˇres WebSocket server(viz. 2.3).
3.3
Rozhran´ı aplikace
Pˇri n´avrhu aplikace bylo c´ılem vytvoˇrit co nejjednoduˇsˇs´ı rozhran´ı, kter´e umoˇzn´ı snadno vytv´aˇret objekty a vyvol´avat jejich metody. Velmi obecn´e ˇreˇsen´ı vyuˇz´ıvaj´ıc´ı reflexi(viz. 2.2) na stranˇe C# umoˇzn ˇuje, aby z´akladn´ı rozhran´ı objektu v JavaScriptu mˇelo pouze 5 metod. T´emˇeˇr kaˇzd´a metoda rozhran´ı aplikace v JavaScriptu m´a jako prvn´ı argument poloˇzku callback, kter´a oznaˇcuje n´azev funkce v JavaScriptu, kter´a bude vyvol´ana po vyplnˇen´ı p˚ uvodn´ı funkce. Toto opatˇren´ı je nutn´e, protoˇze JavaScript je pouze jednovl´aknov´ y jazyk. To znamen´a, ˇze pokud by se v pr˚ ubˇehu skriptu muselo ˇcekat na dokonˇcen´ı nˇejak´e ˇcasovˇe n´aroˇcn´e operace, vyˇradilo by to vˇsechny komponenty webov´e str´anky, kter´e jsou na JavaScriptu z´avisl´e. Z tohoto d˚ uvodu mus´ı vˇsechny ˇcasovˇe n´aroˇcn´e operace prob´ıhat asynchronnˇe. V naˇsem pˇr´ıpadˇe je asynchronn´ı pˇr´ıstup obzvl´aˇstˇe nutn´ y 16
Implementace
Rozhran´ı aplikace
pˇri vytv´aˇren´ı objektu a n´asledn´em vol´an´ı metody tohoto objektu, kter´a mus´ı b´ yt spuˇstˇena aˇz po u ´spˇeˇsn´em zrcadlen´ı nov´eho objektu do JavaScriptu, tedy v callbacku. Aplikace podporuje vytv´aˇren´ı objekt˚ u jednoduch´ ych datov´ ych typ˚ u ve funkc´ıch prim´arnˇe urˇcen´ ych pro jin´e u ´ˇcely, neˇz je vytv´aˇren´ı objekt˚ u. Napˇr´ıklad pokud v parametru vyvol´avan´e metody bude ˇretˇezec ”int:5”, vytvoˇr´ı se doˇcasn´ y objekt typu System.Int32 s hodnotou 5 a tento objekt se pˇred´a vyvol´avan´e metodˇe jako parametr. Tato vlastnost je vˇzdy uvedena v popisu parametr˚ u dan´e funkce. Dalˇs´ı vlastnost, kterou rozhran´ı m´a, je moˇznost potlaˇcen´ı serializace funkc´ı (v´ıce o serializaci funkc´ı v sekci 3.4). Serializace je ˇcasovˇe n´aroˇcn´a operace a t´ımto zp˚ usobem je moˇzn´e ji ˇc´asteˇcnˇe urychlit. Napˇr´ıklad nen´ı potˇreba serializovat metody u ˇcten´ ych dat ze serveru, jejichˇz metody nehodl´ame pouˇz´ıt. Serializace metod se potlaˇc´ı tak, ˇze v dan´em ˇretˇezci pˇred´avan´em metodˇe bude prvn´ı znak roven ’*’. Napˇr´ıklad chceme-li nov´ y objekt uloˇzit pod jm´enem ”dummy” a chceme-li potlaˇcit serializaci funkc´ı u tohoto objektu, pˇred´ame metodˇe parametr s hodnotou ”*dummy”. U parametr˚ u, kter´ ych se tato vlastnost t´ yk´a je to vˇzdy uvedeno d´ale v popisu rozhran´ı.
Z´ akladn´ı rozhran´ı aplikace v JavaScriptu: Tyto metody vys´ılaj´ı prostˇrednictv´ım WebSocket serveru poˇzadavky na vyvol´an´ı stejnojmenn´e metody v meziˇcl´anku aplikace implementovan´e v C#. • AddToWorkpace(callback, itemName, itemType) – Pˇrid´av´a nov´ y objekt do workspace zavol´an´ım vhodn´eho konstruktoru, vyb´ıran´eho podle dan´ ych vstupn´ıch parametr˚ u. Pˇri chybn´em zvolen´ı parametr˚ u metoda vyvol´a v´ yjimku s popisem moˇzn´ ych kombinac´ı parametr˚ u. – Popis parametr˚ u: ∗ callback - jm´eno funkce, kter´a bude spuˇstˇena po u ´spˇeˇsn´em vytvoˇren´ı objektu. ∗ itemName - Jm´eno, pod kter´ ym bude objekt uloˇzen v promˇenn´e workspace. M˚ uˇze obsahovat poˇzadavek na potlaˇcen´ı serializace metod. ∗ itemType - Jm´eno datov´eho typu objektu. M˚ uˇze obsahovat deklaraci jednoduch´ ych datov´ ych typ˚ u. Tak´e m˚ uˇze obsahovat deklaraci generick´ ych datov´ ych typ˚ u (napˇr.: ”System.Collections.Generic.Dictionary<string,int>”) 17
Implementace
Rozhran´ı aplikace
∗ Metodu je moˇzn´e volat s promˇenliv´ ym poˇctem parametr˚ u. Vˇsechny dalˇs´ı parametry jsou povaˇzov´any za jm´ena parametr˚ u ve workspace, se kter´ ymi m´a b´ yt vol´an konstruktor. – Pˇr´ıklad vol´an´ı: opcClient.AddToWorkspace("connectRexServer", serverName, "Opc.Da.Server", "Factory", "URL"); – Pˇr´ıklad protokolu dat pˇren´aˇsen´ ych pˇres WebSocket server: "connectRexServer_|_AddToWorkspace~rexServer; Opc.Da.Server;Factory,URL" • Invoke(callback, itemName, methodName, saveResultName, argsArray) – Vyvol´av´a zvolenou metodu nad vybran´ ym objektem s poˇzadovan´ ymi argumenty. Pokud se uˇzivatel pokouˇs´ı vyvolat metodu se ˇspatn´ ymi argumenty, metoda vyvol´a v´ yjimku s informacemi o moˇzn´ ych zp˚ usobech vol´an´ı dan´e metody. – Popis parametr˚ u: ∗ callback - jm´eno funkce, kter´a bude spuˇstˇena po u ´spˇeˇsn´em vyvol´an´ı metody a kter´e bude pˇred´an obraz n´avratov´e hodnoty vyvolan´e metody. ∗ itemName - Jm´eno objektu ve workspace, nad kter´ ym se bude vyvol´avat metoda. ∗ methodName - Jm´eno metody, kter´a m´a b´ yt vyvol´ana. ∗ saveResultName - Jm´eno, pod jak´ ym se do workspace uloˇz´ı n´avratov´a hodnota metody. M˚ uˇze obsahovat poˇzadavek na potlaˇcen´ı serializace metod. ∗ argsArray - pole jmen parametr˚ u, kter´e maj´ı b´ yt metodˇe pˇred´any. M˚ uˇze obsahovat deklaraci jednoduch´ ych datov´ ych typ˚ u. – Pˇr´ıklad vol´an´ı: opcClient.Invoke("callbackFce","rexServer","Connect", null,["ConnectData"]); – Pˇr´ıklad protokolu dat pˇren´aˇsen´ ych pˇres WebSocket server: "callbackFce_|_Invoke~rexServer;Connect; null;ConnectData" • SetValue(callback, itemName, valueName) – Metoda nastavuje objekt ve wokrspace na urˇcenou hodnotu. 18
Implementace
Rozhran´ı aplikace
– Popis parametr˚ u: ∗ callback - Jm´eno metody, kter´a bude vyvol´ana po u ´spˇeˇsn´em nastaven´ı objektu na poˇzadovanou hodnotu. ∗ itemName - Jm´eno objektu, jehoˇz hodnota m´a b´ yt pˇrenastavov´ana. ∗ valueName - Jm´eno objektu ve workspace, jehoˇz hodnota se pouˇzije pro nastaven´ı objektu. M˚ uˇze obsahovat deklaraci jednoduch´ ych datov´ ych typ˚ u. – Pˇr´ıklad vol´an´ı: opcClient.SetValue(null, "URL.Scheme", "string:opcda"); – Pˇr´ıklad protokolu dat pˇren´aˇsen´ ych pˇres WebSocket server: "null_|_SetValue~URL.Scheme;string:opcda" • Refresh(callback, itemName, boolWithFunctions) – Aktualizuje objekt ve workspace v JavaScriptu. Aktualizace je nutn´a, pokud se hodnoty ˇclen˚ u objektu mˇen´ı po vytvoˇren´ı objektu jin´ ym zp˚ usobem neˇz prostˇrednictv´ım metody SetValue(). Dalˇs´ım moˇzn´ ym vyuˇzit´ım je dodateˇcn´a serializace metod, pokud jsme pˇri vytvoˇren´ı objektu tuto moˇznost potlaˇcili. – Popis parametr˚ u: ∗ callback - Jm´eno funkce, kter´a bude spuˇstˇena po u ´spˇeˇsn´e aktualizaci objektu. ∗ itemName - Jm´eno objektu, kter´ y m´a b´ yt aktualizov´an. ∗ boolWithFunctions - Hodnota typu boolean urˇcuj´ıc´ı, zda se m´a objekt aktualizovat vˇcetnˇe funkc´ı. To m˚ uˇze b´ yt nutn´e, pokud objekt s dan´ ym jm´enem pˇrep´ıˇseme ve workspace jin´ ym objektem. – Pˇr´ıklad vol´an´ı: opcClient.Refresh(null,"group.ReadResults",false); – Pˇr´ıklad protokolu dat pˇren´aˇsen´ ych pˇres WebSocket server: "null_|_Refresh~group.ReadResults;false" • Remove(callback, itemName) – Odstraˇ nuje objekty z promˇenn´e workspace. 19
Implementace
Rozhran´ı aplikace
– Popis parametr˚ u: ∗ callback - Jm´eno funkce, kter´a bude spuˇstˇena po odstranˇen´ı dan´eho objektu. ∗ itemName - Jm´eno objektu, kter´ y m´a b´ yt odstranˇen. – Pˇr´ıklad vol´an´ı: opcClient.Remove(null, "URL"); – Pˇr´ıklad protokolu dat pˇren´aˇsen´ ych pˇres WebSocket server: "null_|_Remove~URL"
Specifick´ e metody rozhran´ı: Tyto metody jsou specifick´e pro JavaScriptovou ˇca´st aplikace a nemaj´ı sv´eho protˇejˇska v meziˇcl´anku implementovan´em v C#. • Connect(host) – Metoda pro pˇripojen´ı objektu v JavaScriptu k WebSocket serveru. – Popis parametr˚ u: ∗ host - URI adresa serveru, ke kter´emu se m´a objekt pˇripojit • OnConnectedToWS() – Metoda, kter´a je spuˇstˇena po u ´spˇeˇsn´em pˇripojen´ı k WebSocket serveru. Pˇredpokl´ad´a se, ˇze klient tuto metodu pˇrep´ıˇse sv´ ym k´odem. • ConnectToREX(callback, serverName) – Metoda speci´alnˇe urˇcen´a pro pˇripojen´ı k OPC serveru v ˇr´ıd´ıc´ım syst´emu REX. Vyuˇz´ıv´a k tomu v´ yˇse zm´ınˇen´e metody pro vytv´aˇren´ı objekt˚ u, nastaven´ı hodnoty a vol´an´ı funkce. – Popis parametr˚ u: ∗ callback - Jm´eno funkce, kter´a bude spuˇstˇena po pˇripojen´ı OPC .NET API k OPC serveru ˇr´ıd´ıc´ıho syst´emu REX. ∗ serverName - Jm´eno, pod kter´ ym bude server uloˇzen ve wokspace. • getItem(name) – Metoda pro z´ısk´an´ı poloˇzky z promˇenn´e workspace. 20
Implementace
Datov´y form´at JSON a serializace funkc´ı
– Popis parametr˚ u: ∗ name - jm´eno poloˇzky nebo ˇretˇezec obsahuj´ıc´ı cestu k poloˇzce ve workspace • getWorkspace() – Metoda, kter´a vrac´ı promˇennou workspace. • SubscriptionCallback(itemsArray) – Metoda, kter´a slouˇz´ı pro zpracov´an´ı asynchronnˇe ˇcten´ ych dat objektem OpcSimpleIO (viz. sekce 3.5). Pˇredpokl´ad´a se, ˇze uˇzivatel pˇrep´ıˇse metodu sv´ ym k´odem. – Popis parametr˚ u: ∗ itemsArray - pole, kter´e obsahuje asynchronnˇe ˇcten´a data
3.4
Datov´ y form´ at JSON a serializace funkc´ı
Rozhran´ı definovan´e v sekci 3.3 je dostateˇcn´e pro z´akladn´ı komunikaci s libovoln´ ym rozhran´ım v .NET. Na druhou stranu nen´ı pˇr´ıliˇs uˇzivatelsky pˇra´telsk´e, nebot’ uˇzivatel mus´ı rozhran´ı v .NET zn´at do t´e m´ıry, aby vˇedˇel jak´a metoda se vol´a s jak´ ymi parametry. Pro vyˇreˇsen´ı tohoto probl´emu byl rozˇs´ıˇren datov´ y form´at JSON tak, aby kromˇe textov´ ych ˇretˇezc˚ u, ˇc´ıseln´ ych hodnot, boolean hodnot a hodnoty null umoˇzn ˇoval nav´ıc pouˇzit´ı funkc´ı jako hodnoty v p´aru kl´ıˇc:hodnota (v´ıce o JSON v sekci 2.4). Rozˇs´ıˇren´ı JSON form´atu umoˇzn ˇuje zrcadlen´ı objektu ze C# do JavaScriptu vˇcetnˇe vlastn´ıch veˇrejn´ ych metod . Samozˇrejmˇe tyto obrazy metod neprov´ad´ı stejn´e u ´kony, ale pouze ve sv´em nitru volaj´ı metodu Invoke() s pˇr´ısluˇsn´ ymi parametry. Tento zp˚ usob nav´ıc umoˇzn ˇuje prov´adˇet typovou kontrolu parametr˚ u uˇz v JavaScriptu pˇred zavol´an´ım metody Invoke() a t´ım zabraˇ nuje nadbyteˇcn´e s´ıt’ov´e komunikaci, kter´a by nastala v pˇr´ıpadˇe, kdy by se uˇzivatel pokouˇsel zavolat metodu s nespr´avn´ ymi parametry pˇr´ımo prostˇrednictv´ım metody Invoke() a o chybn´em zvolen´ı parametr˚ u by se pot´e dozvˇedˇel aˇz po vyvol´an´ı v´ yjimky v C# a jej´ı propagaci do JavaScriptu. Serializace funkc´ı umoˇzn ˇuje aby uˇzivatel pˇristupoval k zvolen´emu API v .NET pomoc´ı obraz˚ u funkc´ı samotn´eho API a manipulovat tak s n´ım v JavaScriptu t´emˇeˇr stejnˇe, jako by sn´ım manipuloval v prostˇred´ı .NET.
21
Implementace
Datov´y form´at JSON a serializace funkc´ı
Pˇ r´ıklady serializace metod Hlaviˇ cky metod v C#: public void bar(double d, object obj); public double foo(int i); public int foo(double d, string str);
Obrazy funkc´ı v JavaScriptu: Obraz uk´azkov´eho objektu je ve workspace uloˇzen pod jm´enem ”dummy”. U pˇret´ıˇzen´ ych metod se nejprve kontroluje poˇcet parametr˚ u obsaˇzen´ ych v poli opcB_argsArray. Pot´e se kontroluj´ı datov´e typy jednotliv´ ych parametr˚ u. Parametry mohou b´ yt bud’ null, nebo to mohou b´ yt ˇretˇezce obsahuj´ıc´ı deklaraci nov´eho objektu jednoduch´eho datov´eho typu (napˇr.: ”int:5 ”), nebo je parametrem jm´eno objektu, pod kter´ ym je uloˇzen ve workspace. V tom pˇr´ıpadˇe se objekt vyhled´a ve wokspace a zkontroluje se jeho ˇclen .dotnetType. V´ yjimku tvoˇr´ı pˇr´ıpad, kdy m´a b´ yt poˇzadovan´ y argument typu object. V tom pˇr´ıpadˇe m˚ uˇze b´ yt parametrem hodnota null nebo libovoln´a deklarace jednoduch´eho typu a nebo jm´eno libovoln´eho objektu, kter´ y je definovan´ y ve workspace. Pokud jsou vˇsechny parametry u ´spˇeˇsnˇe zkontrolov´any, je zavol´ana funkce Invoke(). Pokud se typov´a kontrola nevydaˇr´ı, dojde k vyvol´an´ı v´ yjimky.
Obraz metody bar() function (js_callback, d, obj) { if (d === null || d.split(’:’)[0] === "double" || opcClient.getItem(d).dotnetType === "double") { if (obj === null || obj.split(’:’).length === 2 || opcClient.getItem(obj) !== ’undefined’) { opcClient.Invoke(js_callback, "dummy", "bar", "null", [d, obj]); return; } } throw "There is no ’bar’ method callable with given arguments!"; }
22
Implementace
Datov´y form´at JSON a serializace funkc´ı
Obraz pˇ ret´ıˇ zen´ e metody foo() function (js_callback, opcB_saveResultName, opcB_argsArray) { if (opcB_argsArray.length === 1) { if (opcB_argsArray[0] === null || opcB_argsArray[0].split(’:’)[0] === "int" || opcClient.getItem(opcB_argsArray[0]).dotnetType === "int") { opcClient.Invoke(js_callback, "dummy", "foo", opcB_saveResultName, opcB_argsArray); return; } } if (opcB_argsArray.length === 2) { if (opcB_argsArray[0] === null || opcB_argsArray[0].split(’:’)[0] === "double" || opcClient.getItem(opcB_argsArray[0]).dotnetType === "double") { if (opcB_argsArray[1] === null || opcB_argsArray[1].split(’:’)[0] === "string" || opcClient.getItem(opcB_argsArray[1]).dotnetType === "string") { opcClient.Invoke(js_callback, "dummy", "foo", opcB_saveResultName, opcB_argsArray); return; } } } throw "There is no ’foo’ method callable with given arguments!"; }
23
Implementace
3.5
Zjednoduˇsen´e API pro pˇr´ıstup k OPC
Zjednoduˇ sen´ e API pro pˇ r´ıstup k OPC
D´ıky serializaci funkc´ı nemus´ı uˇzivatel pouˇz´ıvat metodu Invoke() ze z´akladn´ıho rozhran´ı aplikace, ale m˚ uˇze volat poˇzadovan´e metody v C# prostˇrednictv´ım jejich obraz˚ u v JavaScriptu. M˚ uˇze tak vyuˇz´ıvat API, ke kter´emu se aplikace pˇripojuje, v jeho p˚ uvodn´ı podobˇe. Dalˇs´ı moˇznost´ı, kter´a se uˇzivateli nab´ız´ı, je vytvoˇrit si v C# objekt, kter´ y bude poˇzadovan´e API libovolnˇe zaobalovat a nad´ale se z JavaScriptu pˇripojovat pˇr´ımo k tomuto objektu. T´ımto zp˚ usobem si uˇzivatel m˚ uˇze rozhran´ı, se kter´ ym bude nad´ale pracovat, libovolnˇe pˇrizp˚ usobovat podle sv´ ych vlastn´ıch poˇzadavk˚ u. Pro pˇr´ıstup k OPC DataAccess Serveru (jehoˇz implementaci obsahuje ˇr´ıd´ıc´ı syst´em REX) byl vytvoˇren jednoduch´ y objekt, kter´ y si klade za c´ıl ulehˇcovat z´akladn´ı operace z´apis a ˇcten´ı dat vˇcetnˇe asynchronn´ıho ˇcten´ı.
Zjednoduˇ sen´ e rozhran´ı - objekt OpcSimpleIO • OpcSimpleIO(Opc.Da.Server server ) – Konstruktor objektu. – parametr server - pˇripojen´ y server typu Opc DA. Pro vytvoˇren´ı Opc serveru syst´emu REX staˇc´ı zavolat metodu ConnectToREX() z rozhran´ı aplikace v JavaScriptu . • Add R Item(string itemName) – Metoda pˇrid´av´a poloˇzku pro ˇcten´ı. – parametr itemName - jm´eno poloˇzky, kter´a m´a b´ yt pˇrid´ana • Remove R Item(string itemName) – Metoda odeb´ır´a poloˇzku pro ˇcten´ı. – parametr itemName - jm´eno poloˇzky, kter´a m´a b´ yt odebr´ana • Add W Item(string itemName, object value) – Metoda pˇrid´av´a poloˇzku pro z´apis. – parametry: ∗ itemName - jm´eno poloˇzky, kter´a m´a b´ yt pˇrid´ana ∗ value - hodnota, kter´a m´a b´ yt zaps´ana na server 24
Implementace
Zjednoduˇsen´e API pro pˇr´ıstup k OPC
• Remove W Item(string itemName) – Metoda odeb´ır´a poloˇzku pro z´apis. – parametr itemName - jm´eno poloˇzky, kter´a m´a b´ yt odebr´ana • Read() – Metoda pˇreˇcte poloˇzky pˇridan´e metodou Add R Item(). • Write() – Metoda zapisuje poloˇzky pˇridan´e metodou Add W Item(). • ChangeState(string propertyName, object value) – Metoda mˇen´ı hodnoty podm´ınek pro asynchronn´ı ˇcten´ı. – parametry: ∗ propertyName - jm´eno vlastnosti, jej´ıˇz hodnota m´a b´ yt zmˇenˇena Nˇekter´e moˇzn´e hodnoty: · Active - aktivace asynchronn´ıho ˇcten´ı · UpdateRate - perioda obnovov´an´ı dat · KeepAlive - pr˚ ubˇeˇzn´a aktualizace hodnot pro udrˇzen´ı spojen´ı · Deadband - urˇcuje p´asmo necitlivosti na zmˇeny dat · SamplingRate - frekvence ˇcten´ı dat ∗ value - hodnota, kterou m´a dan´a vlastnost nab´ yvat • SwitchSubscriptionState() – Metoda aktivuje nebo deaktivuje asynchronn´ı ˇcten´ı.
25
Implementace
3.6
Zpˇetn´e odezvy a chybov´e hl´aˇsky
Zpˇ etn´ e odezvy a chybov´ e hl´ aˇ sky
Aplikace je navrˇzena tak, aby jak´ ykoliv poˇzadavek z JavaScriptov´e strany vˇzdy vyvolal odpovˇed’ nebo chybovou hl´aˇsku na stranˇe C#, kter´a je pot´e posl´ana zpˇet. Z d˚ uvodu snadn´eho rozliˇsen´ı odezev bylo kaˇzd´e pˇridˇeleno identifikaˇcn´ı ˇc´ıslo, kter´e se pˇrid´av´a ke zpr´avˇe s odezvou.
Identifikaˇ cn´ı ˇ c´ısla odezev: 100x 1001 1002 1003 1004 1005 1006
Mnoˇzina odezev potvrzuj´ıc´ıch korektn´ı pr˚ ubˇeh operac´ı u ´spˇeˇsnˇe pˇrid´an nov´ y objekt do promˇenn´e workspace u ´spˇeˇsn´e nastaven´ı objektu na poˇzadovanou hodnotu u ´spˇeˇsn´e vyvol´an´ı metody u ´spˇeˇsn´e odebr´an´ı objektu z workspace asynchronn´ı upozornˇen´ı na zmˇenu hodnoty prvku OPC serveru u ´spˇeˇsn´e obnoven´ı objektu
200x 2001 2002 2003 2004 2005 2006
Mnoˇzina bˇeˇzn´ ych chyb nezn´am´ y pˇr´ıkaz neoˇcek´avan´a v´ yjimka pokus o pˇr´ıstup k objetu, kter´ y nen´ı ve workspace definovan´ y datov´ y typ objektu nemohl b´ yt identifikov´an chybn´a deklarace generick´eho datov´eho typu chybn´a deklarace jednoduch´eho datov´eho typu
300x 3001 3002
Chyby vznikl´e pˇri vytv´aˇren´ı nov´eho objektu chybn´ y tvar odeslan´eho poˇzadavku snaha o zavol´an´ı neexistuj´ıc´ıho konstruktoru
400x 4001 4002 4003
Chyby vznikl´e pˇri nastavov´an´ı objektu na danou hodnotu chybn´ y tvar odeslan´eho poˇzadavku snaha o nastaven´ı objektu na neexistuj´ıc´ı objekt pokus o nastaven´ı objektu na hodnotu jin´eho datov´eho typu
500x 5001 5002 5003
Chyby vznikl´e pˇri vyvol´av´an´ı metod chybn´ y tvar odeslan´eho poˇzadavku vol´an´ı neexistuj´ıc´ı metody vol´an´ı metody se ˇspatn´ ymi parametry
26
4 Testov´an´ı v´ykonu aplikace 4.1
Reflexe vs. pˇ r´ım´ y pˇ r´ıstup
Reflexe mus´ı b´ yt z principu sv´e funkce (viz. sekce 2.2.2) znatelnˇe pomalejˇs´ı neˇz pˇr´ım´ y pˇr´ıstup. Ot´azkou je ale o kolik je pomalejˇs´ı a do jak´e m´ıry to ovlivˇ nuje v´ ykon aplikace. V tabulce 4.1 jsou v´ ysledky testov´an´ı rychlosti vol´an´ı metody. Testovac´ı metoda neprov´adˇela ˇza´dn´e operace, jen vracela sv˚ uj argument, kter´ ym byl integer. Metoda byla vol´ana 106 -kr´at. Z v´ ysledk˚ u je patrn´e ˇze samotn´e vyvol´an´ı metody reflex´ı je pˇribliˇznˇe 100-kr´at pomalejˇs´ı, pˇr´ım´e zavol´an´ı. V tabulk´ach 4.2 a 4.3 jsou v´ ysledky porovn´av´an´ı reflexivn´ıho a pˇr´ım´eho pˇr´ıstupu pˇri vol´an´ı metod pouˇz´ıvan´ ych pro zisk dat z OPC Serveru. Pˇri prvn´ım mˇeˇren´ı byla vol´ana metoda Add_R_Item(string name) pro pˇrid´an´ı prvku do skupiny pro ˇcten´a data, v druh´em pˇr´ıpadˇe byla zvolena metoda Read(), kter´a vyˇc´ıt´a data ze serveru. Metoda Read() byla vˇzdy spouˇstˇena 1000-kr´at s r˚ uzn´ ymi poˇcty ˇcten´ ych prvk˚ u. Metoda Add_R_Item() byla spuˇstˇena tolikr´at, kolik prvk˚ u bylo pˇrid´av´ano. V ˇc´astech tabulek Pˇr´ır˚ ustek je v procentech vyˇc´ısleno o kolik je pr˚ ubˇeh metody vˇcetnˇe zavol´an´ı delˇs´ı pˇri pouˇzit´ı metody Invoke() vyuˇz´ıvaj´ıc´ı reflexi neˇz pˇri pˇr´ım´em zavol´an´ı. Metoda Invoke() je vˇzdy o nˇeco pomalejˇs´ı, ale maxim´aln´ı namˇeˇren´ y rozd´ıl o hodnotˇe nav´ yˇsen´ı rovn´e 32% nen´ı nijak z´avaˇzn´ y. Toto zpoˇzdˇen´ı nav´ıc nen´ı zp˚ usobeno pouze reflex´ı, nebot’ metoda Invoke() prov´ad´ı i dalˇs´ı operace jako napˇr´ıklad manipulaci s promˇennou workspace nebo zisk hodnoty parametr˚ u z ˇretˇezc˚ u obsahuj´ıc´ıch deklaraci jednoduch´ ych datov´ ych typ˚ u a dalˇs´ı. Ze z´ıskan´ ych v´ ysledk˚ u se d´a vyvodit, ˇze opoˇzdˇen´ı pˇri zavol´an´ı metody reflex´ı je takˇrka zanedbateln´e. Pr˚ ubˇeh a rychlost metod daleko v´ıce z´avis´ı na operac´ıch, kter´e metoda prov´ad´ı, neˇz na zp˚ usobu zavol´an´ı metody. doba trv´an´ı [s] Reflexe Pˇr´ım´e vol´an´ı 1.5109 0.0184 Tabulka 4.1: V´ ysledky testov´an´ı rychlosti reflexe.
27
Testov´an´ı v´ykonu aplikace
Pˇrenos dat
doba trv´an´ı [s] Poˇcet pˇridan´ ych prvk˚ u Reflexe Pˇr´ım´e vol´an´ı Pˇr´ır˚ ustek [%] 10 0.148 0.121 22 50 0.598 0.493 21 100 1.196 0.911 31 500 5.848 4.401 32 1000 11.159 8.848 26 Tabulka 4.2: V´ ysledky testov´an´ı rychlosti vol´an´ı metody Add_R_Item(). doba trv´an´ı [s] Poˇcet ˇcten´ ych prvk˚ u Reflexe Pˇr´ım´e vol´an´ı Pˇr´ır˚ ustek [%] 10 0.411 0.347 18 50 1.109 1.079 3 100 1.942 1.939 <1 500 8.156 7.615 7 1000 17.185 15.106 14 Tabulka 4.3: V´ ysledky testov´an´ı rychlosti vol´an´ı metody Read().
4.2
Pˇ renos dat
Dalˇs´ım faktorem, kter´ y ovlivˇ nuje v´ ykonnost aplikace je pˇrenos dat pˇres WebSocket server (viz. sekce 2.3). Objem dat pˇren´aˇsen´ ych z prohl´ıˇzeˇce na server je velmi mal´ y, nebot’ obsahuje jen pˇr´ıkazy, kter´e se maj´ı na serveru vykonat. Naopak ˇretˇezce obsahuj´ıc´ı serializovan´e objekty, kter´e jsou pos´ıl´any ze serveru prohl´ıˇzeˇci, mohou b´ yt velice rozs´ahl´e. Rychlost pˇrenosu byla testov´ana po lok´aln´ı s´ıti. V re´aln´ ych podm´ınk´ach bude samozˇrejmˇe v´ ykonnost z´aviset na rychlosti pˇripojen´ı. Testov´ana byla rychlost pˇren´aˇsen´ı serializovan´ ych objekt˚ u pro r˚ uzn´e poˇcty objekt˚ u. Pˇrenos dat byl prov´adˇen 1000-kr´at. V´ ysledky jsou zanesen´e v tabulce 4.4.
4.3
Serializace a deserializace objekt˚ u
Dalˇs´ı ˇcasovˇe n´aroˇcnou operac´ı v bˇehu aplikace je nutnost serializace objekt˚ u do form´atu JSON v C# a n´asledn´a deserializace v JavaScriptu. Pˇri 28
Testov´an´ı v´ykonu aplikace
Serializace a deserializace objekt˚ u
Poˇcet pˇren´aˇsen´ ych prvk˚ u doba trv´an´ı [s] 10 0.259 50 1.359 100 3.275 500 25.741 1000 80.838 Tabulka 4.4: V´ ysledky testov´an´ı rychlosti pˇren´aˇsen´ı dat ze serveru. testov´an´ı byla serializace i deserializace provedena 1000kr´at. Pro serializaci nemohla b´ yt vyuˇzita ˇz´adn´a knihovn´ı funkce jazyka C#, protoˇze aplikace vyuˇz´ıv´a specificky upraven´ y form´at JSON rozˇs´ıˇren´ y o funkce (viz. sekce 3.4). Proto byl implementov´an vlastn´ı objekt pro serializaci, kter´ y vyuˇz´ıv´a reflexi. Pro deserializaci je vyuˇz´ıv´ana funkce eval(), kter´a je pˇrirozenou souˇca´st´ı JavaScriptu. Pouˇz´ıv´an´ı t´eto funkce nen´ı obecnˇe pˇr´ıliˇs doporuˇcov´ano, protoˇze sebou nese jist´a bezpeˇcnostn´ı rizika. V naˇsem pˇr´ıpadˇe je ale tato funkce pouˇz´ıv´ana jen pro zpracov´an´ı ˇretˇezc˚ u z vlastn´ıho serveru, takˇze k ˇza´dn´emu ohroˇzen´ı doj´ıt nem˚ uˇze. Nemohli b´ yt vyuˇzity ˇza´dn´e moduly pro JavaScript, kter´e zajiˇst’uj´ı zpracov´an´ı JSON form´atu kv˚ uli obsahu funkc´ı, coˇz tyto moduly nepodporuj´ı. V´ ysledky mˇeˇren´ı lze nal´ezt v tabulce 4.5. doba trv´an´ı [s] Poˇcet prvk˚ u Serializace Deserializace 10 0.662 0.160 50 3.392 0.834 100 7.499 1.585 500 33.191 8.054 1000 71.897 17.566 Tabulka 4.5: V´ ysledky testov´an´ı rychlosti serializace a deserializace objekt˚ u
29
Testov´an´ı v´ykonu aplikace
4.4
Celkov´y v´ykon aplikace
Celkov´ y v´ ykon aplikace
Lze pˇredpokl´adat, ˇze aplikace najde nejvˇetˇs´ı vyuˇzit´ı pˇri vyˇc´ıt´an´ı dat z OPC Serveru. Z toho d˚ uvodu byl celkov´ y v´ ykon aplikace testov´an na metodˇe Read(). Ze serveru byla 1000-kr´at ˇctena skupina dat a mˇeˇrena byla doba od prvn´ıho odesl´an´ı poˇzadavku na ˇcten´ı dat z JavaScriptu aˇz po posledn´ı pˇr´ıjem dat. Testov´an´ı bylo provedeno po lok´aln´ı s´ıti. V´ ysledky jsou v tabulce 4.6. V ˇca´sti frekvence ˇcten´ı je pˇribliˇzn´a hodnota v herz´ıch, kter´a odpov´ıd´a frekvenci s jakou je aplikace schopna ˇc´ıst dan´e mnoˇzstv´ı prvk˚ u. Pro dosaˇzen´ı lepˇs´ıch v´ ysledk˚ u je moˇzn´e vyuˇz´ıt asynchronn´ı ˇcten´ı (viz. sekce 3.5), kde odpad´a neust´al´e pos´ıl´an´ı pˇr´ıkaz˚ u z JavaScriptu a n´asledn´e vol´an´ı metody pro ˇcten´ı. Poˇcet ˇcten´ ych prvk˚ u doba trv´an´ı [s] Frekvence ˇcten´ı [Hz ] 10 1.893 528 50 6.149 162 100 11.939 83 500 68.992 14 1000 167.257 6 Tabulka 4.6: V´ ysledky testov´an´ı rychlosti ˇcten´ı dat z OPC serveru.
30
5 Uk´azka Pro uk´azku funkce aplikace byla vytvoˇrena jednoduch´a SVG grafika (viz. obr. 5.1) ve webov´em prohl´ıˇzeˇci v podobˇe hodin, kter´a je ˇr´ızena daty pˇrij´ıman´ ymi prostˇrednictv´ım vytvoˇren´e aplikace z ˇr´ıd´ıc´ıho syst´emu REX Control. Sch´ema zapojen´ı algoritmu v syst´emu REX lze nal´ezt v Pˇr´ıloze 5. Algoritmus prob´ıh´a s periodou 1s.
Popis v´ yznamn´ ych ˇ c´ ast´ı k´ odu webov´ e str´ anky:
Inicializace pˇ ripojen´ı - V prvn´ım kroku, kter´ y je nutn´e prov´est pˇred pˇripojen´ım k OPC Serveru, se pˇrekr´ yv´a metoda OnConnectedToWS(), kter´a se vykon´a po u ´spˇeˇsn´em pˇripojen´ı k WebSocket serveru, a vytvoˇr´ı se pˇripojen´ı. Dalˇs´ım krokem je vytvoˇren´ı pˇripojen´ı k OPC serveru syst´emu REX metodou ConnectToREX(). Po u ´spˇeˇsn´em pˇripojen´ı se vyvol´a metoda addGroup(), ve kter´e se vytv´aˇr´ı objekt OpcSimpleIO konstruktorem, kter´ y pˇrij´ım´a OPC server jako sv˚ uj argument. opcClient.Connect("ws://localhost:8181/"); opcClient.OnConnectedToWS = function () { opcClient.ConnectToREX("opcClient.addGroup", "rexServer"); } opcClient.addGroup = function () { opcClient.AddToWorkspace("opcClient.initIO", "group", "OPCBridge.OpcSimpleIO", "rexServer"); }
Inicializace ˇ cten´ı a z´ apisu dat - Pouˇzit´ım metod Add_R_Item(), respektive Add_W_Item(), se inicializuje ˇcten´ı, respektive z´apis, poloˇzek na server. Zapisuj´ı se data, kter´a odpov´ıdaj´ı aktu´aln´ımu ˇcasu. opcClient.initIO = function () { var date = new Date(); var group = opcClient.getItem("group"); group.Add_R_Item(null, "string:rex_clock.Seconds.y"); 31
Uk´azka
group.Add_R_Item(null, "string:rex_clock.Minutes.y"); group.Add_R_Item(null, "string:rex_clock.Hours.y"); group.Add_W_Item(null, "string:rex_clock.InitSeconds.ycn", "int:" + (date.getSeconds() + 1)); group.Add_W_Item(null, "string:rex_clock.InitMinutes.ycn", "int:" + date.getMinutes()); group.Add_W_Item(null, "string:rex_clock.InitHours.ycn", "int:" + date.getHours()); group.Write("opcClient.WaitForInitRex", null); } ˇ Cten´ ı dat ze serveru - Ze serveru jsou pˇreˇctena data a n´aslednˇe ve funkci StartClock() jsou podle nich nastaveny hodiny v SVG grafice. Je aktivov´ano asynchronn´ı ˇcten´ı dat metodou SwitchSubscriptionState(). opcClient.InitClock = function () { var group = opcClient.getItem("group"); group.SwitchSubscriptionState(null); group.Read("opcClient.StartClock", null); }
Spuˇ stˇ en´ı algoritmu a asynchronn´ı pˇ r´ıjem dat - Po u ´spˇeˇsn´em nastaven´ı hodin v SVG grafice je do skupiny dat pro z´apis pˇrid´ana poloˇzka rex_clock.Start.YCN a je na ni zaps´ana hodnota true, ˇc´ımˇz se spust´ı algoritmus v syst´emu REX. Zmˇenami hodnot v syst´emu REX doch´az´ı ke generov´an´ı asynchronn´ıch ud´alost´ı, kter´e o tom informuj´ı uˇzivatele v JavaScriptu. Uˇzivatel na tyto ud´alosti reaguje pˇrekryt´ım metody SubscriptionCallback(). V naˇsem pˇr´ıpadˇe se v t´eto metodˇe manipuluje s ruˇciˇckami hodin. opcClient.StartClock = function (itemsArray) { ... group.Add_W_Item(null, "string:rex_clock.Start.YCN", "bool:true"); group.Write(null, null); } opcClient.SubscriptionCallback = function (itemsArray) { ... }
32
Uk´azka
11
12
1 2
10
3
9 8
4 7
6
5
Obr´azek 5.1: Pˇr´ıklad jednoduch´e vektorov´e SVG grafiky.
33
6 Z´avˇer V souˇcasn´e dobˇe je velk´ ym trendem vytv´aˇret aplikace v podobˇe tenk´ ych klient˚ u, protoˇze to pˇrin´aˇs´ı ˇradu v´ yhod. Implementovan´a aplikace tak´e vznikla v tomto duchu a d´ıky tomu jedin´e, co klient na sv´em poˇc´ıtaˇci potˇrebuje v pˇr´ıpadˇe, ˇze je aplikace spuˇstˇena na serveru, je internetov´ y prohl´ıˇzeˇc. V´ ysledky testov´an´ı v´ ykonnosti aplikace z kapitoly 4 jsou pro porovn´an´ı zaneseny do grafu 6.1. Je patrn´e, ˇze aplikace je nejv´ıce limitov´ana serializac´ı prvk˚ u v programovac´ım jazyce C#. To by mohlo b´ yt problematick´e pˇri ˇcten´ı velk´eho poˇctu dat s poˇzadavkem na vysokou frekvenci ˇcten´ı. Pˇri dalˇs´ım v´ yvoji aplikace by tedy bylo vhodn´e implementovat serializaci efektivnˇejˇs´ım zp˚ usobem neˇz jak´ y je pouˇzit v aktu´aln´ı verzi nebo aktu´aln´ı ˇreˇsen´ı patˇriˇcnˇe optimalizovat. N´aroˇcn´a serializace je jistˇe nejvˇetˇs´ı nev´ yhodou zvolen´eho zp˚ usobu implementace. Pro dosaˇzen´ı vyˇsˇs´ıho v´ ykonu je moˇzn´e potlaˇcit serializaci metod pro objekty, jejichˇz metody uˇzivatel nehodl´a pouˇz´ıvat. Dalˇs´ı moˇznost´ı je pro vyvol´av´an´ı metod pˇr´ımo vyuˇz´ıvat metodu Invoke(), kter´a nen´ı na serializaci metod z´avisl´a. T´ım se ale uˇzivatel pˇriprav´ı o typovou kontrolu argument˚ u v JavaScriptu. K pˇrednostem aplikace jistˇe patˇr´ı nez´avislost na pouˇzit´em API, ke kter´emu se aplikace pˇripojuje. Pro jeho zmˇenu nebo pˇrid´an´ı nov´eho API staˇc´ı odpov´ıdaj´ıc´ım zp˚ usobem upravit dan´e pole s informacemi o assemblies1 , ze kter´ ych m´a aplikace zpracov´avat Metadata a vytv´aˇret podle nich objekty. D´ıky tomu m˚ uˇze b´ yt aplikace v budoucnu pouˇzita s novˇejˇs´ımi verzemi OPC .NET API nebo pracovat s nˇekolika r˚ uzn´ ymi API z´aroveˇ n. Dalˇs´ı v´ yhodou je moˇznost si poˇzadovan´e API libovolnˇe zaobalit do objektu v .NET a pro pr´aci s API nad´ale pouˇz´ıvat rozhran´ı tohoto objektu prostˇrednictv´ım obraz˚ u jeho metod v JavaScriptu. Aplikace umoˇzn ˇuje pˇripojen´ı libovoln´eho mnoˇzstv´ı klient˚ u z´aroveˇ n, pˇriˇcemˇz kaˇzd´ y z nich m´a k dispozici vlastn´ı promˇennou workspace. Z vlastnost´ı OPC .NET API d´ale vypl´ yv´a, ˇze kaˇzd´ y z tˇechto klient˚ u se m˚ uˇze pˇripojit na libovoln´e mnoˇzstv´ı OPC Server˚ u. Funkˇcnost aplikace byla ovˇeˇrena na OPC Serveru ˇr´ıd´ıc´ıho syst´emu REX a na Matrikon OPC Simulation Serveru. Pr´ace by dle m´eho n´azoru mˇela splˇ novat poˇzadavky, kter´e na ni byly kladeny. Aplikace by se nyn´ı mˇela dostat do stavu d˚ ukladn´eho testov´an´ı v praxi, coˇz pravdˇepodobnˇe povede k dalˇs´ım optimalizaˇcn´ım z´asah˚ um. Pˇri v´ yvoji byla vyuˇzita z´akladn´ı implementace WebSocket serveru, kterou mi poskytl m˚ uj vedouc´ı pr´ace Ing. Miroslav Koc´anek. 1
string[] _assembliesFullNames
34
Z´avˇer
90 80 70
Čtení prvků Serializace Deserializace Přenos dat
čas [ t ]
60 50 40 30 20 10 0 1 10
2
10 Počet prvků
10
3
Obr´azek 6.1: Porovn´an´ı v´ ykonu jednotliv´ ych souˇca´st´ı aplikace
35
Literatura ´ [jso()] Uvod do JSON. Dostupn´e z: http://www.json.org/json-cz.html. [web(2011)] WebSocket.org, 2011. org/.
Dostupn´e z: http://www.websocket.
[Cog(1995-2010)] What is OPC? Cogent Real-Time Systems Inc., 1995-2010. Dostupn´e z: http://www.opcdatahub.com/WhatIsOPC.html#note1. [Hickson(2012)] HICKSON, I. May 2012. W3C, 2012. websockets/.
The WebSocket API - Editor´s Draft 2 Dostupn´e z: http://dev.w3.org/html5/
[Hurlbut(1998)] HURLBUT, M. A Tutorial on Behavioral Reflection and its Implementation, 1998. Dostupn´e z: http: //www2.parc.com/csl/groups/sda/projects/reflection96/docs/ malenfant/ref96/ref96.html. [Ian Fette(2011)] IAN FETTE, A. M. The WebSocket Protocol. Google Inc., Isode Ltd., 2011. Dostupn´e z: http://tools.ietf.org/html/rfc6455. [Mic(2012a)] COM:Component Object Model Technologies. Microsoft, 2012a. Dostupn´e z: http://www.microsoft.com/com/default.mspx. [Mic(2012b)] Reflection (C# Programming Guide). Microsoft, 2012b. Dostupn´e z: http://msdn.microsoft.com/en-us/library/ms173183% 28v=vs.80%29.aspx. [Neitzel(2009)] NEITZEL, L. EXPRESS interface - Technical Overview, 2009. Dostupn´e z: http://www.slideshare.net/JimCahill/ express-interface-xi-technical-overview. [OPC(2012)] OPC Foundation - The Interoperability Standart for Industrial Automation & Related Domains. OPC Foundation, 2012. Dostupn´e z: http://www.opcfoundation.org/. 36
Pˇ r´ıloha
37
ˇ ILOHA ´ PR
ˇ ILOHA ´ PR
Handshake klienta: GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Origin: http://example.com Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13 Handshake poch´azej´ıc´ı ze strany serveru: HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= Sec-WebSocket-Protocol: chat Pˇr´ıloha 1: Pˇr´ıklad handshake klienta a serveru technologie WebSocket. 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-------+-+-------------+-------------------------------+ |F|R|R|R| opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16/64) | |N|V|V|V| |S| | (if payload len==126/127) | | |1|2|3| |K| | | +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + | Extended payload length continued, if payload len == 127 | + - - - - - - - - - - - - - - - +-------------------------------+ | |Masking-key, if MASK set to 1 | +-------------------------------+-------------------------------+ | Masking-key (continued) | Payload Data | +-------------------------------- - - - - - - - - - - - - - - - + : Payload Data continued ... : + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | Payload Data continued ... | +---------------------------------------------------------------+ Pˇr´ıloha 2: Podoba jednoho r´amce protokolu WebSocket. 38
ˇ ILOHA ´ PR
ˇ ILOHA ´ PR
Pˇr´ıloha 3: Legenda k jednotliv´ ym ˇ c´ astem r´ amce. FIN: 1 bit • Tento bit znaˇc´ı zda se jedn´a o posledn´ı r´amec zpr´avy. RSV1, RSV2, RSV3: kaˇzd´ y 1 bit • Tyto bity mus´ı b´ yt nastaveny na hodnotu 0, pokud pˇri handshake nedoˇslo k dojedn´an´ı nˇejak´ ych rozˇs´ıˇren´ı protokolu. Opcode: 4 bity • Popisuje druh a tvar dat, pˇren´aˇsen´ ych r´amcem. Definovan´e jsou n´asleduj´ıc´ı moˇzn´a nastaven´ı: – %x0 - navazuj´ıc´ı r´amec – %x1 - textov´ y r´amec – %x2 - bin´arn´ı r´amec – %x3-7 - hodnoty rezervovan´e pro budouc´ı nekontroln´ı r´amce – %x8 - poˇzadavek na uzavˇren´ı pˇripojen´ı – %x9 - ping – %xA - pong – %xB-F - hodnoty rezervovan´e pro budouc´ı kontroln´ı r´amce Mask: 1 bit • Popisuje zda jsou pˇren´aˇsen´a data maskov´ana. Pˇri nastaven´ı na hodnotu 1 mus´ı v ˇc´asti r´amce Masking-key b´ yt pˇr´ıtomen kl´ıˇc pro odmaskov´an´ı dat. Maskov´ana jsou data, pos´ılan´a klientem. Payload length: 7 bit˚ u, 7+16 bit˚ u nebo 7+64 bit˚ u
39
ˇ ILOHA ´ PR
ˇ ILOHA ´ PR
• Sekvence bit˚ u, obsahuj´ıc´ı velikost pˇren´aˇsen´ ych dat. Pokud tato hodnota je v intervalu [0,125], pak odpov´ıd´a d´elce pˇren´aˇsen´ ych dat. Pokud je ale tato hodnota 126, n´asleduj´ıc´ı 2 byty obsahuj´ı 16 bitov´ y unsigned integer, jehoˇz hodnota odpov´ıd´a d´elce pˇren´aˇsen´ ych dat. Pokud je tato hodnota dokonce 127, pot´e se na dalˇs´ıch 8 bytech nach´az´ı 64 bitov´ y unsigned integer, jehoˇz hodnota odpov´ıd´a d´elce pˇren´aˇsen´ ych dat. Masking-key: 0 nebo 4 byty • Vˇsechny r´amce pos´ılan´e klientem serveru jsou maskovan´e 32 bitovou hodnotou, kter´a je souˇca´st´ı r´amce. Tuto poloˇzku r´amec obsahuje pouze tehdy, je-li poloˇzka r´amce Mask nastavena na hodnotu 1. • Maskovac´ı kl´ıˇc je 32-bitov´a hodnota n´ahodnˇe zvolen´a klientem. Klient mus´ı vˇzdy pˇri pˇr´ıpravˇe nov´eho r´amce vytvoˇrit nov´ y kl´ıˇc, kter´ y mus´ı b´ yt nepˇredv´ıdateln´ y. Payload data • V posledn´ı ˇca´sti r´amce se nach´azej´ı samotn´a data, kter´a maj´ı b´ yt pˇrenesena. Tato data vzniknou spojen´ım libovoln´ ych aplikaˇcn´ıch dat spolu s daty rozˇs´ıˇren´ı protokolu, pokud toto rozˇs´ıˇren´ı bylo domluveno v otev´ırac´ım handshake.
40
ˇ ILOHA ´ PR
ˇ ILOHA ´ PR
[Constructor(DOMString url, optional DOMString protocols), Constructor(DOMString url, optional DOMString[] protocols)] interface WebSocket : EventTarget { readonly attribute DOMString url; // ready state const unsigned short CONNECTING = 0; const unsigned short OPEN = 1; const unsigned short CLOSING = 2; const unsigned short CLOSED = 3; readonly attribute unsigned short readyState; readonly attribute unsigned long bufferedAmount; // networking [TreatNonCallableAsNull] attribute Function? onopen; [TreatNonCallableAsNull] attribute Function? onerror; [TreatNonCallableAsNull] attribute Function? onclose; readonly attribute DOMString extensions; readonly attribute DOMString protocol; void close([Clamp] optional unsigned short code, optional DOMString reason); // messaging [TreatNonCallableAsNull] attribute Function? onmessage; attribute DOMString binaryType; void send(DOMString data); void send(ArrayBuffer data); void send(Blob data); }; Pˇr´ıloha 4: WebSocket rozhran´ı
41
ˇ ILOHA ´ PR
ˇ ILOHA ´ PR
0 CNR_1 u1 u2 y SW SSW_2
1 CNR_4
off
0 InitSeconds
Start
u1 y u2 Seconds
uc uo OR1 y OR2 OR3 OR4 SWU_1
u1 y u2 SW SSW_1
u1 Y u2 REL_1
60 CNR_8
0 CNR_3 0 CNR_5
0 InitMinutes
u1 y u2 SW SSW_3
uc uo OR1 y OR2 OR3 OR4 SWU_2
1 CNR_6
u1 y u2 Minutes u1 y u2 SW SSW_4
u1 y u2 SW SSW_5 0 InitHours
uc uo OR1 y OR2 OR3 OR4 SWU_3
u1 Y u2 REL_2
0 CNR_2
60 CNR_7
0 CNR_9 1 CNR_10
u1 y u2 Hours
u1 y u2 SW SSW_6
u1 Y u2 REL_3
12 CNR_11
0 CNR_12
Pˇr´ıloha 5: Sch´ema zapojen´ı uk´azkov´eho pˇr´ıkladu v syst´emu REX Control.
42