åæ
ãµãŒããŒæäœã®æŠå¿µ
ãã®èšäºãæžããšããã¢ã€ãã¢ã¯ãMathematicaã䜿çšããŠããŒã«ã«ãã¹ãäžã«ç¬èªã®ãµãŒããŒãäœæããæ¹æ³ã«ã€ããŠèª¬æããŠããHabrahabrã«é¢ããåæ§ã®èšäºãèªãã åŸã«æãã€ããŸããã WebãµãŒããŒèªäœã¯ãPythonãšTornadoæ¡åŒµå¯èœãµãŒããŒã䜿çšããŠäœæãããŸããã 圌ã¯ãªã¯ãšã¹ããåŠçããå¿çãjson圢åŒã§éä¿¡ããããžãã¯ã¯Mathematicaã«å®è£ ãããŸããã åæã«ãã³ãã³ãã©ã€ã³ã䜿çšããŠPythonãšMathematicaã®éã®éä¿¡ãè¡ããããµãŒããŒãžã®åãªã¯ãšã¹ããæ°åŠã®ã³ã¢ãåèµ·åããŸããã ãã®ä»ã®è©³çŽ°ã«ã€ããŠã¯ã @ Nilisã®èšäºãåç §ããŠãã ãã ã ããã§ã¯ãåæ§ã®æ©èœãå®è¡ããåçŽãªã³ãŒãã®äœææ¹æ³ã瀺ããŸããã€ãŸããèŠæ±ãåŠçããŠå¿çãéä¿¡ããhttpãµãŒããŒãäœæããŸãã ããã«ãWolframèšèªã®èå³æ·±ãæ©èœãšãã®æ§æã瀺ããããšæããŸãã
空ã®ãµãŒããŒå®è£
æãç°¡åãªæ¹æ³ã¯ãmainé¢æ°ã§å®è£ ãéå§ããŠãããããã«å éžã«ç§»åããããšã§ãã æžã蟌ãã«ã¯ã次ã®ã³ãã³ããå®è¡ããŠSocketLink`ã³ã³ããã¹ããããŒãããå¿ èŠããããŸãã
Needs["SocketLink`"];
ãã®åŸããã®ã³ã³ããã¹ãã®æ©èœã䜿çšå¯èœã«ãªããŸãã 次ã®ããã«ãå«ãŸããæ©èœãæ£ç¢ºã«ç¢ºèªã§ããŸãã
Information["SocketLink`*"];
ãœã±ãããªã³ã¯ | |
---|---|
CreateAsynchronousServer | CreateServerSocket |
CreateClientSocket | OpenSocketStreams |
ããããã次ã®ãšããã§ããããšã説æããŸãããã
- CreateClientSocket [ port ] -port - portã䜿çšããŠãœã±ãããäœæããŸãã
- CreateServerSocket [ host ã port ] -ãã¹ã- ãã¹ãã«æ¥ç¶ããããŒã- ããŒãã䜿çšããã¯ã©ã€ã¢ã³ããœã±ãããäœæããŸãã
- OpenSocketStreams [ ãœã±ãã ] -ãœã±ãã- ãœã±ããã®å ¥åºåã¹ããªãŒã ãéããŸã ã
- CreateAsynchronousServer [ socket ã handler ] -æå®ãããsocket- socketããã³handler- handler㧠ããµãŒããŒããäœæããŸãã
æãåçŽãªã±ãŒã¹ã§ã¯ããã®ã³ã³ããã¹ãã®2ã€ã®é¢æ°ã®ã¿ãå¿ èŠã§ãã
CreateAsynchronousServerããã³CreateServerSocket ã ãã¡ãããäžèŠãããšãã¹ãŠãæºåãã§ããŠããããµãŒããŒãã äœæ ãããæå³ããªãããã«èŠããŸãã ããããããã¯ããã§ã¯ãããŸããã CreateAsynchronousServer-æå®ããããœã±ããããªãã¹ã³ãã以å€ã¯äœãã§ããŸããã ãããã£ãŠãä»ã®ãã¹ãŠãå®è£ ããå¿ èŠããããŸãã ãŸã第äžã«ãå ¥ååŒæ°ã«å¶éãæã€ãã«ããŒé¢æ°ãäœæãããšããã§ãããã
MathematicaSimpleServer[socket_Socket, handler_Handler] := CreateAsynchronousServer[socket, handler];
Mathematicaã®éãŠãŒã¶ãŒåãã®èª¬æã " ïŒ= "èšå·ã®å·ŠåŽïŒ SetDelayed [] ïŒã¯ãå®è¡åŸã«ã¡ã¢ãªã«ä¿åããããã³ãã¬ãŒãã§ãã å³åŽã«ã¯ããã³ãã¬ãŒããæ€åºããããšãã«å®è¡ãããã«ãŒã«ããããŸãã socket_Socketã®åœ¢åŒã§æå®ãã-æåã®åŒæ°ããœã±ããã§ãªããã°ãªããªãããšã瀺ããŸãã handler_Handlerãã¿ãŒã³-2çªç®ã®åŒæ°ã¯Handleråã§ãªããã°ãªããªãããšã瀺ããŸãã ãã®ã¿ã€ãã¯çŸåšååšããŸããã ãã ããMathematicaã¯ããã«æ³šæãæãããå ¥åãã©ã¡ãŒã¿ã®1ã€ãšããŠååšããªãåãåãå ¥ããé¢æ°ãäœæããããšãèš±å¯ããŸãã
ãã®ã¿ã€ããååšããªãå Žåã¯ãäœæããå¿ èŠããããŸãã ãã£ãŠã¿ãŸãããã 次ã®ã³ãŒãã¯ã TagSetDelayed []ã䜿çšããŠMathematicaã§ç¬èªã®åçŽãªããŒã¿åãäœæããæ¹æ³ã瀺ããŠããŸãã
(* getters for Handler *) Handler /: GetRequestParser[Handler[parser_RequestParser, _]] := parser; Handler /: GetResponseGenerator[Handler[_, generator_ResponseGenerator]] := generator; (* setters for Handler *) Handler /: SetRequestParser[handler_Handler, parser_RequestParser] := Handler[handler, GetResponseGenerator[handler]]; Handler /: SetResponseGenerator[handler_Handler, generator_ResponseGenerator] := Handler[GetRequestParser[handler], generator];
Mathematica以å€ã®ãŠãŒã¶ãŒåãã®æ§æã®èª¬æã ã /ïŒ ã èšå· ïŒ TagSetDelayed [] ïŒã¯ãå·ŠåŽã«ããããŒã¿åïŒ Handler ïŒã«å¯ŸããŠã®ã¿ãé¢æ°ã®æäœãåå®çŸ©ããããã®å®çŸ©ãå®å šã«å³åŽã«ããããšãæå³ããŸãã é¢æ°ãåŒã³åºããããšãã«å®è¡ãããã«ãŒã«ã¯ãéåžžã©ãããã ïŒ= ãèšå·ã®å³åŽã«ãããŸãã ãã®ã¡ãœããã¯ãä¿è·ãããã·ã¹ãã æ©èœã«å¯ŸããŠãæ©èœããŸãã ãã®å Žåãé¢æ°èªäœã®ååã§ã¯ãªããååã«é¢é£ããå€æŽãããããã§ãã ããã€ãã®æ©èœã¯ããã³ãã¬ãŒãå ã®èšå·ã /ïŒ ããšã ïŒ= ãã®éã®ãã³ãã©ãŒã¿ã€ããæ瀺çã«ã©ããã«é 眮ããå¿ èŠãããããšã§ãïŒãã ããæäžäœã§ã¯ãããŸããïŒã ç¹°ãè¿ããŸãããäžèšã®4ã€ã®é¢æ°ã¯ãååšããªãããŒã¿åã䜿çšããŠå®çŸ©ãããŠããããšã«æ³šæããŠãã ããïŒ RequestParser ã ResponseGenerator ã ããã§æåŸã®ã¿ããã¯ãã³ãã©ãŒã®å®çŸ©ã«æ®ããŸã-ããã¯ããµãŒããŒå ã§ãã³ãã©ãŒãåŒã³åºããããšãã«å®è¡ããããã³ãã¬ãŒããäœæããããã§ãã 圌ã¯ãå ¥åãšåºåã¹ããªãŒã ã®2ã€ã®èŠçŽ ã®ãªã¹ããå ¥åãšããŠåãå ¥ããå¿ èŠããããŸãã ãããã®ã¹ã¬ããã§ã»ãšãã©ãã¹ãŠã®ã¢ã¯ã·ã§ã³ãå®è¡ã§ããŸãã åè¿°ã®ããã«ããã³ãã©ãŒã¯å ¥åã¹ããªãŒã ãèªã¿åããåºåã¹ããªãŒã ã«æžã蟌ãå¿ èŠããããŸãã 次ã®ããã«å®è£ ããŸãã
handler_Handler[{input_InputStream, output_OutputStream}] := Module[{ requestParser = GetRequestParser[handler], responseGenerator = GetResponseGenerator[handler], request = "", response = "" }, (* read data from input stream of the socket *) {request} = If[# != {}, FromCharacterCode[#], Print[DateString[], "\nERROR"]; Close[input]; Close[output]; Return[]]& @ Last[Reap[While[True, TimeConstrained[ Sow[BinaryRead[input]], 0.01, (Close[input]; Break[]) ];];]]; (* logging *) Print[DateString[], "\nREQUEST:\n\n", request]; (* processing request *) response = responseGenerator[requestParser[request]]; (* logging and writing data to the output stream *) Switch[response, _String, Print[DateString[], "\nRESPONSE:\n\n", response]; BinaryWrite[output, ToCharacterCode[response]], {__Integer}, Print[DateString[], "\nRESPONSE:\n\n", FromCharacterCode[response]]; BinaryWrite[output, response]; ]; Close[output]; ];
å¥åŠãªããšã«ããããMathematicaã§ã¯ããã³ãã¬ãŒãã®å·ŠåŽã«äžæã®ååãäœæããå¿ èŠã¯ãŸã£ãããããŸããã èŠåºããšå éšã³ã³ãã³ããå«ãè€éãªè¡šçŸã«ããããšãã§ããŸãã é¢æ°å®çŸ©ãäœæãããã®æ¹æ³ã¯ãã£ãã«äœ¿çšãããŸãããããã®å Žåã¯éåžžã«äŸ¿å©ã§ãã ãã³ãã©ãŒã®å éšã³ã³ãã³ãã¯ããµãŒããŒã®ãã°å šäœã決å®ããŸãã ããã§ã空ã®ãµãŒããŒå®è£ ã®æºåãã§ããŸããã 圌女ã¯åããŸããã圹ã«ç«ã€ããšã¯äœãããŸããã çµå±ã®ãšããããã¹ãŠã®ãªã¯ãšã¹ãåŠçã¯ãååšããªãé¢æ°requestParser ã responseGeneratorã«ãããŸãã ãã®å Žåãæååãå ¥åã«éä¿¡ãããçµæã¯æååïŒãŸãã¯Swich []ã¹ã€ããã®2çªç®ã®ãªãã·ã§ã³ã§ç€ºåããããã€ãã®ãªã¹ãïŒã§ããå¿ èŠããããŸãã ãªã¯ãšã¹ããèªãã åŸã«èª°ãäœãè¿ãããšãæ°ã«ããŸãããããã®ã äœã§ã ããé¢æ°ã«ãã£ãŠæ£ããåŠçãããŠåçãäœæããããšããæ¡ä»¶ã§ã®ã¿ã§ãã
ãªã¯ãšã¹ãåŠç
ãµãŒããŒã®æºåãã§ããã®ã§ã RequestParserã¿ã€ãã®å®è£ ãåŠçããå¿ èŠããããŸãã æåã«äœ¿çšãããŸãã äžèšã®Handlerã®å ŽåãšãŸã£ããåãæ¹æ³ã§ãæãåçŽãªå®çŸ©ãäœæããŸãã
requestParser_RequestParser[request_String] := request;
ãã®å®çŸ©ã«ããã°ãé¢æ°ã¯ã¯ãšãªæååèªäœãè¿ãã ãã§ãã éå§ããã«ã¯ååã§ãã ããã§ãã¹ãŠãåãã«ãªããŸããããå¿çãžã§ãã¬ãŒã¿ãŒã®å ŽåïŒ
responseGenerator_ResponseGenerator[parsed_String] := "HTTP/1.1 200 OK Content-Length: 1024 Connection: close <!DOCTYPE html> <html> <head> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /> <title>MathematicaSimpleServer</title> </head> <body> Hello from mathematica simple server! </body> </html>"
ãžã§ãã¬ãŒã¿ãŒã®å®çŸ©ãæãç°¡åã§ãã ããã¯ã衚瀺ãããããŒãžã®htmlããŒã¯ã¢ããã«æ¥ç¶ãããåãªãå¿çè¡ã§ãã ããã§ãã¹ãŠæºåå®äºã§ãïŒ ãµãŒããŒãèµ·åããŠãã©ã®ããã«æ©èœãããã確èªã§ããŸãã ãããè¡ãã«ã¯ã次ã®ã³ãŒããå®è¡ããŸãã
socket = CreateServerSocket[8888]; handler = Handler[RequestParser[], ResponseGenerator[]]; server = MathematicaSimpleServer[socket, handler];
ããã§ãã©ãŠã¶ãéããã¢ãã¬ã¹httpïŒ// localhostïŒ8888 /ã«ç§»åããŸãã ãã©ãŠã¶ã«ã¯ã次ã®ãããªããŒãžã衚瀺ãããŸãã
Thu 19 Jan 2017 01:22:00 REQUEST: GET / HTTP/1.1 Accept: text/html, application/xhtml+xml, image/jxr, */* Accept-Language: ru-RU User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393 Accept-Encoding: gzip, deflate Host: localhost:8888 Connection: Keep-Alive
Wed 18 Jan 2017 14:56:45 RESPONSE: HTTP/1.1 200 OK Content-Length: 1024 Connection: close <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>MathematicaSimpleServer</title> </head> <body> Hello from mathematica simple server! </body> </html>
ãã£ãïŒ ãµãŒããŒã¯åŒãç¶ãæ©èœããŸãã ResponseGenerator []ã®åŒã³åºãäžã«è¿ãããã衚瀺ãããhtmlããŒãžã®ã³ãŒããåæ¢ããªãã§å€æŽããããšãããšã©ããªããŸããïŒ ããããã£ãŠã¿ãŸããã-ããäžåºŠé¢æ°ãå®çŸ©ããŠãã ããïŒ
responseGenerator_ResponseGenerator[parsed_String] := ("HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Content-Length: " <> ToString[StringLength[#]] <> " Connection: close " <> #)& @ "<!DOCTYPE html> <html> <head> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /> <title>MathematicaSimpleServer</title> </head> <body> Hello from mathematica simple server! <br/> we changed the server logic without stopping ;) </body> </html>"
äžèšã®ã³ãŒããå®è¡ããŠããŒãžãæŽæ°ãããšãå€æŽãããã³ã³ãã³ãããã©ãŠã¶ãŒã«è¡šç€ºãããŸãã WebãµãŒããŒãåæ¢ããŠã ResponseGeneratorããã³RequestParserã®æ°ããå®çŸ©ãè¿œå ãç¶ããããšã¯ã§ããŸããã ããã«ããããããããããæ¢ããæ¹æ³ãç¥ãããšã¯æçšã§ãã ã³ãŒããå®è¡ããã ãã§ååã§ãã
SocketLink`Sockets`CloseSocket[socket]; StopAsynchronousTask[server];
ãµãŒããŒæ¡åŒµ
å°ãæºåã ä»åŸåé¡ãçºçããªãããã«ããã®ããã¥ã¡ã³ãã®å Žæãäœæ¥ãã£ã¬ã¯ããªãšããŠããã«èšå®ããŸãã
SetDirectory[NotebookDirectory[]];
æããã«ããã©ãŠã¶ãŠã£ã³ããŠã«2è¡ã衚瀺ããããšã¯ãMathematicaã®æ©èœã®è¯ããã¢ã³ã¹ãã¬ãŒã·ã§ã³ã§ã¯ãããŸããã ãã¹ãã®ããã«ãåçŽãªhtml ã€ã³ããã¯ã¹ããŒãžãäœæããŸãããã 以äžã«ããŒãžã³ãŒãã瀺ããŸãã ãµãŒããŒãè¿ãä»ã®ã¢ãã¬ã¹ãžã®ãªã³ã¯ãæ¢ã«ããã€ããããŸãã åçå šäœãäœæããé¢æ°ãè¿œå ãããŸããã
IndexPage[] := "<!DOCTYPE html> <html> <head> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /> <title>MathematicaSimpleServer</title> <link rel=\"icon\" type=\"image/png\" href=\"/favicon.png\"/> </head> <body> Index page for the mathematica simple server <ul> <li><a href=\"/graphic?Sin\" >graphic</a></li> <li><a href=\"/page.html\" >page</a></li> <li><a href=\"notebook.nb\" >notebook</a></li> </ul> </body> </html>"; ResponseString[page_String] := StringTemplate["HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Content-Length: `length` Connection: close `page`"][<|"length" -> StringLength[page], "page" -> page|>]; ResponseString[page_String, length_Integer] := StringTemplate["HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Content-Length: `length` Connection: close `page`"][<|"length" -> length, "page" -> page|>];
å¿çè¡ãšããŒãžããŒã¯ã¢ããã³ãŒããæ¥ç¶ããé¢æ°-ResponseString [] -ã«ã¯2ã€ã®å®çŸ©ããããŸããæåã®å®çŸ©ã§ã¯ãããŒãžãµã€ãºãèšç®ãã Content-LengthããããŒã®å€ãçµæã«çœ®ãæããŸãã 2çªç®ã®å®çŸ©ã§ã¯ãå¿çæ¬æã®ãµã€ãºãåå¥ã«æå®ã§ããŸãã åè¿°ã®ããã«ãã¡ã€ã³ããŒãžã«ã¯ããã€ãã®ãªã³ã¯ããããŸãã ãªã³ã¯ã¯ãäœããã®ãµãŒããŒããžãã¯ãå®è¡ãããã¢ãã¬ã¹ã®1ã€ã«ã€ãªãããšæ³å®ãããŸãã åèšã§4ã€ã®ç°ãªãã±ãŒã¹ããããŸã-ããã¯ãã¡ã€ã³ããŒãžèªäœã®è¡šç€ºãä»»æã®ãã£ãŒããžã®ãªã³ã¯ãhtmlããŒãžãããã³æ°åŠã®æ¢è£œã®ããŒãããã¯ãã圢æãããããŒãžãžã®ãªã³ã¯ã§ãã åã±ãŒã¹ãåå¥ã«æ€èšããå¿ èŠããããŸãã æåã®ã±ãŒã¹ãã¡ã€ã³ããŒãžã®èªã¿èŸŒã¿ã GETèŠæ±ãã¢ãã¬ã¹ã/ããŸãã¯ã/ indexãã§åä¿¡ãããå Žåã«ã®ã¿å®è¡ãããŸãã ãã®äœæã®ç¢ºèªæ¹æ³ã¯ïŒ ãããè¡ãã«ã¯ããŸããŸãªæ¹æ³ããããŸãã 以äžã¯ãæã人æ°ã®ãããã®ã§ã¯ãªããèå³æ·±ããã®ã§ãã ãŸãã RequestParserããŒã¿åã®Keysããã³Parté¢æ°ã次ã®ããã«åå®çŸ©ããŸãã
RequestParser /: Keys[RequestParser[rules___Rule]] := {rules}[[All, 1]]; RequestParser /: Part[RequestParser[___, "Address" -> function: (_Symbol|_Function), ___], "Address"] := function;
äžèšã®åŒã®æ§æã説æãã䟡å€ããããŸãã rules___Rule-ä»»æã®ïŒãŒããå«ãïŒæ°ã®çœ®æã«ãŒã«ãæã€ãã³ãã¬ãŒãã§ãã ããã¯ãä»»æã®æ°ã®åŠçé¢æ°ã䜿çšããŠRequestParserãäœæã§ããKeysé¢æ°ã䜿çšããŠãããã®é¢æ°ã®ååããã¹ãŠååŸã§ããããšãæå³ããŸãã èå³æ·±ãããšã«ãKeysã¯Protectedå±æ§ãæã€ã·ã¹ãã é¢æ°ã§ããããã®é¢æ°ã®å€æŽãçŠæ¢ããŠããŸããã TagSetDelayedã䜿çšããŠã¿ã€ããæå®ãããšããããè¡ãããšãã§ããŸãã åæ§ã«ãçµã¿èŸŒã¿ã®Parté¢æ°ãåå®çŸ©ãããŸããã åè¿°ã®ããã«ã RequestParserã¯è€éãªåŒã§ããããã®äžã«äžé£ã®ã«ãŒã«ãå«ããå¿ èŠããããšæ³å®ãããŠããŸãã åã«ãŒã«ã¯ããŒãšå€ïŒåŠçããé¢æ°ïŒã§ãã ãªãããããã¹ãŠå¿ èŠãªã®ã§ããïŒ å€æ°ã®æ¡ä»¶ãšã¯ãšãªæååãã§ãã¯ãèšè¿°ããããšã¯éåžžã«å°é£ã§ãã ãªã¯ãšã¹ãããã§ãã¯ããããã«æ£èŠè¡šçŸãŸãã¯ãã³ãã¬ãŒããéžæããã®ãæªãå Žåãã³ãŒãã®äžéšãå°éäžèœã«ãªããããå®çŸ©ã®é åºãééããã®ã¯ããã«ç°¡åã§ãã äžåºŠã«è€æ°ã®é¢æ°ã«ãã£ãŠ1ã€ã®èŠæ±ãåŠçããçµæãé¢æ°åãšçµæã®ãã¢ãšã®é¢é£ä»ãã®åœ¢åŒã§è¿ãæ¹ãã¯ããã«ç°¡åã§ãã 以äžã¯ããã®ã¡ãœããã®å®è£ ã§ãã
requestParser_RequestParser[request_String] /; MatchQ[requestParser, RequestParser[_String -> (_Symbol|_Function)]] := Association[Map[Function[key, key -> (requestParser[[key]])[request]], Keys[requestParser]]];
ããã§ãåãé¢æ°ãäœæããå¿ èŠããããŸãã ãªã¯ãšã¹ãã¡ãœããããã¢ãã¬ã¹ãååŸããé¢æ°ã¯1ã€ã ãã§ããäœæè ã®æ³ååã¯ããªã¯ãšã¹ãã®æåã®è¡ã®ã¢ãã¬ã¹ã®éãã ãã«ãµãŒããŒã®äœæ¥ã®ãã¹ãŠã®ã°ãã€ããå ¥ããããšãã§ããããã§ãã
TakeAddress[request_String] := First[StringCases["GET " ~~ address___ ~~ " HTTP/" -> address][request]];
Mathematicaã«æ £ããŠããªã人ã®ããã«-èšèªã®æåååŒã«ã¯å€ãã®èå³æ·±ãæ§é ããããŸãã äžèšã®èšèšã¯çŽæçã§ãæåã®è¡ã§GETãšHTTPã®éã«ãããã¹ãŠã®ããã¹ããéžæããã ãã§ãã 以åã®ãµãŒããŒå®è£ ã§ã¯ãå¿çãžã§ãã¬ãŒã¿ãŒã¯èŠæ±ãã³ãã©ãŒãè¿ããæååãåŠçããŸããã ãã ããããŒãšå€ã®ãã¢ã®é¢é£ä»ãããã®é¢æ°ã®å ¥åã«æž¡ãããŸãã ãã®ããããžã§ãã¬ãŒã¿ãŒã¯ãçµæã®é¢é£ä»ããå¿çã«å€æã§ããæ°ããå®çŸ©ãäœæããå¿ èŠããããŸãã
responseGenerator_ResponseGenerator[parsed_Association] /; parsed[["Address"]] == "/" || parsed[["Address"]] == "/index" := ResponseString[IndexPage[]];
æ°ãããã³ãã©ãŒã§ãµãŒããŒãåèµ·åããŸãã çŸåšã RequestParserå ã«ã¯ããã¹ãŠã®å¿çãåŠçãããé¢æ°åïŒãã¢ãã¬ã¹ãïŒããã³é¢æ°èªäœïŒ TakeAddress ïŒã®æ瀺çãªæ瀺ããããŸãã
socket = CreateServerSocket[8888]; handler = Handler[RequestParser["Address" -> TakeAddress], ResponseGenerator[]]; server = MathematicaSimpleServer[socket, handler];
ã¡ã€ã³ããŒãžã¯æ©èœããŠããŸãã ãªã¯ãšã¹ãã®æ£ããåŠçãä»ã®ãªãœãŒã¹ã«è¿œå ããŸãã ãããã®æåã¯ãæå®ãããé¢æ°ã®ã°ã©ããååŸããè©Šã¿ã§ãã æåã«ãå¿çãžã§ãã¬ãŒã¿ãŒã«å®çŸ©ãè¿œå ããŸãã Mathematicaã®ãã1ã€ã®èå³æ·±ãæ©èœã ä»ã®ã¿ã€ãã®åŒæ°ãŸãã¯ç°ãªãæ°ãæå®ããã ãã§ãªããé¢æ°ããªãŒããŒã©ã€ãã§ããŸãã ãŸããã /; ãèšå·ã䜿çšããŠé¢æ°ãå®è¡ããããã®ä»»æã®è€éãªæ¡ä»¶ã確ç«ããããšãã§ããŸã ïŒ Condition [] ïŒã " /; "èšå·ã®åŸãš " ïŒ= "èšå·ã®åã«ããã³ãã¬ãŒãèªäœïŒååãšåŒæ°/é¢æ°ã®ã·ã°ããã£ïŒã®éã«æ¡ä»¶ãèšè¿°ããã®ãæã䟿å©ã§ãã
responseGenerator_ResponseGenerator[parsed_Association] /; StringMatchQ[parsed[["Address"]], "/graphic?" ~~ ___] := Module[{function = ToExpression[StringSplit[parsed[["Address"]], "?"][[-1]]]}, ResponseString[ExportString[Plot[function[x], {x, -5, 5}], "SVG"]] ];
ãããã©ã®ããã«æ©èœãããã確èªã§ããŸã-ããŒãžhttpïŒ// localhostïŒ8888 / indexã®æåã®ãªã³ã¯ã«ç§»åããããåã«httpïŒ// localhostïŒ8888 / graphicïŒSinã«ç§»åããŸãã çŸåšã以äžã衚瀺ãããŸãã
../graphic?Sin write ../graphic?CosããŸãã¯Log / Exp / Sqrt / Function [xãx ^ 3] /ãªã©ã®ä»£ããã«ã察å¿ããã°ã©ããããŒãžã«è¡šç€ºãããŸãã 次ã«ãäœæ¥ãã£ã¬ã¯ããªãŸãã¯ãµããã£ã¬ã¯ããªã®ããããã«ãããã³ãã©ãŒã«ä»»æã®htmlããŒãžã衚瀺ããæ©èœãè¿œå ããŸãã ãŸããã³ãŒãã䜿çšããŠãã®ããŒãžãäœæããŸãã
Export["page.html", TableForm[Table[{ToString[i] <> "!", i!}, {i, 1, 9}]], "HTML"];
æ®å¿µãªãããäžèšã®è¡ã®ã³ãŒããå®è¡ãããšãMathematicaåŒãhtml圢åŒã«ãšã¯ã¹ããŒãããã®ã«æéããããããšãããã«ããããŸãã æ°åŠã§ã¯ãå€ãã®ããŒãžãŸãã¯ä»ã®èŠçŽ ïŒç»å/è¡šïŒãäœæããããšã¯é£ãããããŸãããããã®ãã¹ãŠã®ããŒã¿ãæ¯åãšã¯ã¹ããŒãããããšã¯ãæšæºçãªæ段ã«ããäœæãããå€§å¹ ã«æéãããããŸãã ããã ãã¹ãŠã®ããŒãžãæ¢ã«ååšãããã¹ãããŒãžãä¿åãããµãŒããŒã®äœæ¥ãã£ã¬ã¯ããªã®ãã£ã¹ã¯ã«ãããšä»®å®ããŸãã ããã衚瀺ããŠã¿ãŠãã ããã ãã®å ŽåãããŒãžãšãã®èŠçŽ ã®ããããããã€ãã®ãªã¹ããšããŠã€ã³ããŒããããå¿çããããŒã®ããè¡ã«å¯Ÿå¿ãããã€ãã®ãªã¹ãã«æ¥ç¶ãããŸãã
responseGenerator_ResponseGenerator[parsed_Association] /; FileExistsQ[FileNameJoin[{Directory[], parsed[["Address"]]}]] && StringTake[parsed[["Address"]], -3] != ".nb" := Module[{path = FileNameJoin[{Directory[], parsed[["Address"]]}], data}, data = Import[path, "Byte"]; Join[ToCharacterCode[ResponseString["", Length[data]]], data] ];
äºæ³ã©ããããµãŒããŒã¯æŽæ°ã®éä¹å€ã®ããŒãã«ããã©ãŠã¶ã«è¿ããŸããã æåŸã®ã±ãŒã¹ã ä¿åããã¡ã¢åž³ããã©ãŠã¶ã«è¡šç€ºããŸãã äœæ¥ãã£ã¬ã¯ããªã§ãã³ãŒãã䜿çšããŠæ°ããNotebook.nbãäœæããŸãã
notebook = CreateDocument[{TextCell["Bubble sort","Section"], ExpressionCell[Defer[list = RandomInteger[{0, 9}, 20]], "Input"], ExpressionCell[Defer[list //. {firsts___, prev_, next_, lasts___} :> {firsts, next, prev, lasts} /; next < prev], "Input"] }]; NotebookEvaluate[notebook, InsertResults -> True]; NotebookSave[notebook, FileNameJoin[{Directory[], "notebook.nb"}]] NotebookClose[notebook];
ããã§ãhtmlããŒãžãèŠæ±ããããšãã«çºçããã¢ã¯ã·ã§ã³ãšåæ§ã®ã¢ã¯ã·ã§ã³ãå®è¡ããŸãã ãã ããhtmlã³ãŒããè¿ãåã«ãã¡ã¢åž³ã¯ãŸãhtmlã«å€æãããŸãã
responseGenerator_ResponseGenerator[parsed_Association] /; FileExistsQ[FileNameJoin[{Directory[], parsed[["Address"]]}]] && StringTake[parsed[["Address"]], -3] == ".nb" := Module[{path, data, notebook}, path = FileNameJoin[{Directory[], parsed[["Address"]]}]; notebook = Import[path, "NB"]; Export[path <> ".html", notebook, "HTML"]; data = Import[path <> ".html", "Byte"]; Join[ToCharacterCode[ResponseString["", Length[data]]], data] ];
ãã¡ããããã©ãŠã¶ã«ããŒãããã¯ãæ£ç¢ºã«è¡šç€ºãããããã§ã¯ãããŸããã ããã¯ãã¹ãŠãMathã¡ã¢åž³ãhtmlã«ãšã¯ã¹ããŒããããæ¹æ³ã«äŸåããŸãã ãŸãããµãŒããŒã§ã¯ããªãœãŒã¹ãäžè¶³ããŠããå Žåã«ãŠãŒã¶ãŒã«è¡šç€ºããããšã©ãŒããŒãžãè¿œå ãã䟡å€ããããŸãã
responseGenerator_ResponseGenerator[parsed_Association] /; !FileExistsQ[FileNameJoin[{Directory[], parsed[["Address"]]}]] := Join[ToCharacterCode[StringReplace[ResponseString["Page not found"], "200 OK" -> "404 !OK"]]];
æããã«ããã®èšäºã«ç€ºãããŠããWebãµãŒããŒã®å®è£ ã¯ãã»ãŒå®å šã§ã¯ãããŸããã ããã«ãããã«ã¯å€§ããªæ¬ ç¹ããããŸãã äŸãšããŠãå°ãªããšããµãŒããŒã2ã€ã®ã³ãŒãã®ã¿ãè¿ãããšãã§ãããšããäºå®ãåŒçšããããšãã§ããŸãïŒ200ãš404ããããã£ãŠãæ瀺ãããã³ãŒãã¯å®éšç/å®èšŒçã§ãããšæãããèŠãããŸãã
æ³çåŽé¢
èè ã«ç¥ãããããã«ãªã£ããããæšæºã®Wolfram Mathematicaã©ã€ã»ã³ã¹ã§ã¯ãåæ¥ç®çãšå人ç®çã®äž¡æ¹ã§ãµãŒããŒã¢ããªã±ãŒã·ã§ã³å ã§æ°åŠã³ã¢ã䜿çšããããšã¯èš±å¯ãããŠããŸããã ãã®å¶éã¯ãWebã«æ¥ç¶ãã¹ãã§ã¯ãªãã¹ã±ãžã¥ãŒã«ãããã¿ã¹ã¯ã«ã¯é©çšãããŸããã Wolfram Researchã«ã¯ã倧èŠæš¡ãªïŒããã§ã¯ãªãïŒãµãŒããŒãµã€ãã¢ããªã±ãŒã·ã§ã³ãå®è£ ããããã®ç¬èªã®éåžžã«åªãããã©ãããã©ãŒã ããããŸã-ããã¯webMathematicaã§ãã æ³åŸã®åé¡ãåé¿ãããµãŒããŒã§Wolframèšèªã䜿çšã§ããããã«ããã®ã¯webMathematicaã®ã©ã€ã»ã³ã¹ã§ãããã¢ããªã±ãŒã·ã§ã³ããã®äžã§éçºãããŠãããã©ããïŒwebMathematicaïŒã¯é¢ä¿ãªããã©ã€ã»ã³ã¹ãè³Œå ¥ããå¿ èŠããããŸãã èè ã¯èªåã®ã³ãŒããã©ã€ã»ã³ã¹å¥çŽã«éåããŠããªããšèããŠãããããããã§ã¯çµã¿èŸŒã¿ããŒã«ã䜿çšããŠlocalhostã§MathematicaãWebãµãŒããŒãå®è¡ã§ããããã«ããããã°ã©ã ã®ããã¹ãã®ã¿ã瀺ããŸãã çµå±ã®ãšãããç¯çœªèªäœã説æããæ¢åµã¯ç¯çœªã§ã¯ãããŸããã
ãããã«
ãã®èšäºã§ã¯ããŸããWolframèšèªã®èå³æ·±ãæ§æäžã®ç¹åŸŽã瀺ããããšæããŸããã éæšæºçãªæ¹æ³ã§ç¹å®ã®åé¡ã解決ãããšãã«ãé¢æ°ãã«ãŒã«ãããã³æ¡ä»¶ãäœæããããŸããŸãªæ¹æ³ã ãããŠããã®ã¬ã€ããMathematicaãšãã®æ©èœã®åŠç¿ãšçµã¿åãããããšã§ãããã¢ãWebéçºãå®è·µã§ããããã«ãªãããšãé¡ã£ãŠããŸãã 次ã«ãã³ãŒããæ¹åããããã®ããããçš®é¡ã®ãã³ãããã®ã¿ã¹ã¯ã®ãã¬ãŒã ã¯ãŒã¯å ã§ã®å®è£ ã®èããããã³æ¹å€ãšã³ã¡ã³ããæåŸ ããŠããŸãã ãã®äœåãå«ãããŒãããã¯ã¯ã次ã®ãªã³ã¯ããããŠã³ããŒãã§ããŸãã ãæž èŽããããšãããããŸããïŒ