diff --git a/ipython-profile/ipython_config.py b/ipython-profile/ipython_config.py
index c399197..ec0bb70 100644
--- a/ipython-profile/ipython_config.py
+++ b/ipython-profile/ipython_config.py
@@ -1,3 +1,2 @@
c = get_config()
-c.KernelManager.kernel_spec = [ "mono", r"%kexe", "{connection_file}"]
c.NotebookApp.extra_static_paths = [ r"%kstatic" ]
\ No newline at end of file
diff --git a/paket.dependencies b/paket.dependencies
index d7879a8..71b392d 100644
--- a/paket.dependencies
+++ b/paket.dependencies
@@ -2,7 +2,7 @@ source https://www.nuget.org/api/v2
nuget FSharp.Compiler.Service 3.0.0 framework: >= net451
nuget FSharp.Core.Microsoft.Signed 3.1.1.1 framework: >= net45
-nuget NetMQ 3.3.0.11
+nuget NetMQ 3.3.3.1
nuget Newtonsoft.Json 5.0.8 framework: >= net45
nuget FSharp.Charting 0.90.5 framework: >= net45
nuget FAKE
diff --git a/paket.lock b/paket.lock
index d85573d..e67c2fd 100644
--- a/paket.lock
+++ b/paket.lock
@@ -1,11 +1,13 @@
NUGET
remote: https://www.nuget.org/api/v2
specs:
+ AsyncIO (0.1.18)
FAKE (4.23.6)
FSharp.Charting (0.90.5) - framework: >= net45
FSharp.Compiler.Service (3.0) - framework: >= net451
FSharp.Core.Microsoft.Signed (3.1.1.1) - framework: >= net45
- NetMQ (3.3.0.11)
+ NetMQ (3.3.3.1)
+ AsyncIO (>= 0.1.18)
Newtonsoft.Json (5.0.8) - framework: >= net45
xunit (2.1) - framework: >= net451
xunit.assert (2.1)
diff --git a/src/IfSharp.Kernel/IfSharp.Kernel.fsproj b/src/IfSharp.Kernel/IfSharp.Kernel.fsproj
index cdc8ec7..7ff32fc 100644
--- a/src/IfSharp.Kernel/IfSharp.Kernel.fsproj
+++ b/src/IfSharp.Kernel/IfSharp.Kernel.fsproj
@@ -122,6 +122,26 @@
-->
+
+
+
+
+ ..\..\packages\AsyncIO\lib\net35\AsyncIO.dll
+ True
+ True
+
+
+
+
+
+
+ ..\..\packages\AsyncIO\lib\net40\AsyncIO.dll
+ True
+ True
+
+
+
+
@@ -145,6 +165,15 @@
+
+
+
+ ..\..\packages\NetMQ\lib\net35\NetMQ.dll
+ True
+ True
+
+
+
@@ -166,4 +195,4 @@
-
+
\ No newline at end of file
diff --git a/src/IfSharp.Kernel/Kernel.fs b/src/IfSharp.Kernel/Kernel.fs
index 4eaa42c..4ff16d7 100644
--- a/src/IfSharp.Kernel/Kernel.fs
+++ b/src/IfSharp.Kernel/Kernel.fs
@@ -16,26 +16,30 @@ type IfSharpKernel(connectionInformation : ConnectionInformation) =
// startup 0mq stuff
let context = NetMQContext.Create()
-
// heartbeat
- let hbSocket = context.CreateRequestSocket()
- do hbSocket.Bind(String.Format("{0}://{1}:{2}", connectionInformation.transport, connectionInformation.ip, connectionInformation.hb_port))
-
- // shell
- let shellSocket = context.CreateRouterSocket()
- do shellSocket.Bind(String.Format("{0}://{1}:{2}", connectionInformation.transport, connectionInformation.ip, connectionInformation.shell_port))
+ let hbSocket = context.CreateRouterSocket()
+ let hbSocketURL =String.Format("{0}://{1}:{2}", connectionInformation.transport, connectionInformation.ip, connectionInformation.hb_port)
+ do hbSocket.Bind(hbSocketURL)
// control
let controlSocket = context.CreateRouterSocket()
- do controlSocket.Bind(String.Format("{0}://{1}:{2}", connectionInformation.transport, connectionInformation.ip, connectionInformation.control_port))
+ let controlSocketURL = String.Format("{0}://{1}:{2}", connectionInformation.transport, connectionInformation.ip, connectionInformation.control_port)
+ do controlSocket.Bind(controlSocketURL)
// stdin
let stdinSocket = context.CreateRouterSocket()
- do stdinSocket.Bind(String.Format("{0}://{1}:{2}", connectionInformation.transport, connectionInformation.ip, connectionInformation.stdin_port))
+ let stdinSocketURL = String.Format("{0}://{1}:{2}", connectionInformation.transport, connectionInformation.ip, connectionInformation.stdin_port)
+ do stdinSocket.Bind(stdinSocketURL)
// iopub
let ioSocket = context.CreatePublisherSocket()
- do ioSocket.Bind(String.Format("{0}://{1}:{2}", connectionInformation.transport, connectionInformation.ip, connectionInformation.iopub_port))
+ let ioSocketURL = String.Format("{0}://{1}:{2}", connectionInformation.transport, connectionInformation.ip, connectionInformation.iopub_port)
+ do ioSocket.Bind(ioSocketURL)
+
+ // shell
+ let shellSocket = context.CreateRouterSocket()
+ let shellSocketURL =String.Format("{0}://{1}:{2}", connectionInformation.transport, connectionInformation.ip, connectionInformation.shell_port)
+ do shellSocket.Bind(shellSocketURL)
let data = new List()
let payload = new List()
@@ -96,21 +100,20 @@ type IfSharpKernel(connectionInformation : ConnectionInformation) =
ignore (hmac.TransformFinalBlock(Array.zeroCreate 0, 0, 0))
BitConverter.ToString(hmac.Hash).Replace("-", "").ToLower()
- let recvAll (socket: NetMQSocket) = socket.ReceiveMessages()
+ let recvAll (socket: NetMQSocket) = socket.ReceiveMultipartBytes()
/// Constructs an 'envelope' from the specified socket
let recvMessage (socket: NetMQSocket) =
// receive all parts of the message
- let message =
- recvAll (socket)
- |> Seq.map decode
- |> Seq.toArray
+ let message = (recvAll (socket)) |> Array.ofSeq
+ let asStrings = message |> Array.map decode
// find the delimiter between IDS and MSG
- let idx = Array.IndexOf(message, "")
+ let idx = Array.IndexOf(asStrings, "")
+
let idents = message.[0..idx - 1]
- let messageList = message.[idx + 1..message.Length - 1]
+ let messageList = asStrings.[idx + 1..message.Length - 1]
// detect a malformed message
if messageList.Length < 4 then failwith ("Malformed message")
@@ -172,7 +175,7 @@ type IfSharpKernel(connectionInformation : ConnectionInformation) =
msg.Append(encode parent_header)
msg.Append(encode "{}")
msg.Append(encode content)
- socket.SendMessage(msg)
+ socket.SendMultipartMessage(msg)
/// Convenience method for sending the state of the kernel
@@ -191,12 +194,25 @@ type IfSharpKernel(connectionInformation : ConnectionInformation) =
let kernelInfoRequest(msg : KernelMessage) (content : KernelRequest) =
let content =
{
- protocol_version = [| 4; 0 |];
- ipython_version = Some [| 1; 0; 0 |];
- language_version = [| 1; 0; 0 |];
+ protocol_version = "4.0.0";
+ implementation = "ifsharp";
+ implementation_version = "4.0.0";
+ banner = "";
+ help_links = [||];
language = "fsharp";
+ language_info =
+ {
+ name = "fsharp";
+ version = "4.3.1.0";
+ mimetype = "text/x-fsharp";
+ file_extension = ".fs";
+ pygments_lexer = "";
+ codemirror_mode = "";
+ nbconvert_exporter = "";
+ };
}
+ sendStateBusy msg
sendMessage shellSocket msg "kernel_info_reply" content
/// Sends display data information immediately
@@ -407,11 +423,12 @@ type IfSharpKernel(connectionInformation : ConnectionInformation) =
/// Handles a 'shutdown_request' message
let shutdownRequest (msg : KernelMessage) (content : ShutdownRequest) =
-
+ logMessage "shutdown request"
// TODO: actually shutdown
let reply = { restart = true; }
- sendMessage shellSocket msg "shutdown_reply" reply
+ sendMessage shellSocket msg "shutdown_reply" reply;
+ System.Environment.Exit(0)
/// Handles a 'history_request' message
let historyRequest (msg : KernelMessage) (content : HistoryRequest) =
@@ -442,7 +459,6 @@ type IfSharpKernel(connectionInformation : ConnectionInformation) =
logMessage (sbOut.ToString())
while true do
-
let msg = recvMessage (shellSocket)
try
@@ -456,16 +472,27 @@ type IfSharpKernel(connectionInformation : ConnectionInformation) =
| HistoryRequest(r) -> historyRequest msg r
| ObjectInfoRequest(r) -> objectInfoRequest msg r
| InspectRequest(r) -> inspectRequest msg r
- | _ -> logMessage (String.Format("Unknown content type. msg_type is `{0}`", msg.Header.msg_type))
+ | _ -> logMessage (String.Format("Unknown content type on shell. msg_type is `{0}`", msg.Header.msg_type))
with
| ex -> handleException ex
+ let doControl() =
+ while true do
+ let msg = recvMessage (controlSocket)
+ try
+ match msg.Content with
+ | ShutdownRequest(r) -> shutdownRequest msg r
+ | _ -> logMessage (String.Format("Unexpected content type on control. msg_type is `{0}`", msg.Header.msg_type))
+ with
+ | ex -> handleException ex
+
/// Loops repeating message from the client
let doHeartbeat() =
try
while true do
- hbSocket.Send(hbSocket.Receive())
+ let hb = hbSocket.ReceiveMultipartBytes() in
+ hbSocket.SendMultipartBytes(hb)
with
| ex -> handleException ex
@@ -485,5 +512,6 @@ type IfSharpKernel(connectionInformation : ConnectionInformation) =
/// Starts the kernel asynchronously
member __.StartAsync() =
- Async.Start (async { doHeartbeat() } )
+ //Async.Start (async { doHeartbeat() } )
Async.Start (async { doShell() } )
+ Async.Start (async { doControl() } )
\ No newline at end of file
diff --git a/src/IfSharp.Kernel/ShellMessages.fs b/src/IfSharp.Kernel/ShellMessages.fs
index de11f12..e8b906d 100644
--- a/src/IfSharp.Kernel/ShellMessages.fs
+++ b/src/IfSharp.Kernel/ShellMessages.fs
@@ -334,30 +334,68 @@ type CommOpen = obj
type KernelRequest = obj
+type KernelReply_LanguageInfo =
+ {
+ // # Name of the programming language that the kernel implements.
+ // # Kernel included in IPython returns 'python'.
+ name: string;
+
+ // # Language version number.
+ // # It is Python version number (e.g., '2.7.3') for the kernel
+ // # included in IPython.
+ version: string;
+
+ // # mimetype for script files in this language
+ mimetype: string;
+
+ // # Extension including the dot, e.g. '.py'
+ file_extension: string;
+
+ // # Pygments lexer, for highlighting
+ // # Only needed if it differs from the 'name' field.
+ pygments_lexer: string;
+
+ // # Codemirror mode, for for highlighting in the notebook.
+ // # Only needed if it differs from the 'name' field.
+ codemirror_mode: string;
+
+ // # Nbconvert exporter, if notebooks written with this kernel should
+ // # be exported with something other than the general 'script'
+ // # exporter.
+ nbconvert_exporter: string;
+ }
+
+type KernelReply_HelpLink = { text: string; url: string; }
+
type KernelReply =
{
- // # Version of messaging protocol (mandatory).
+ // # Version of messaging protocol.
// # The first integer indicates major version. It is incremented when
// # there is any backward incompatible change.
// # The second integer indicates minor version. It is incremented when
// # there is any backward compatible change.
- protocol_version: array;
-
- // # IPython version number (optional).
- // # Non-python kernel backend may not have this version number.
- // # The last component is an extra field, which may be 'dev' or
- // # 'rc1' in development version. It is an empty string for
- // # released version.
- ipython_version: Option>;
-
- // # Language version number (mandatory).
- // # It is Python version number (e.g., [2, 7, 3]) for the kernel
- // # included in IPython.
- language_version: array;
-
- // # Programming language in which kernel is implemented (mandatory).
- // # Kernel included in IPython returns 'python'.
- language: string
+ protocol_version: string;
+
+ // # The kernel implementation name
+ // # (e.g. 'ipython' for the IPython kernel)
+ implementation: string;
+
+ // # Implementation version number.
+ // # The version number of the kernel's implementation
+ // # (e.g. IPython.__version__ for the IPython kernel)
+ implementation_version: string;
+
+ // # Information about the language of code for the kernel
+ language_info: KernelReply_LanguageInfo;
+ language: string;
+
+ // # A banner of information about the kernel,
+ // # which may be desplayed in console environments.
+ banner : string;
+
+ // # Optional: A list of dictionaries, each with keys 'text' and 'url'.
+ // # These will be displayed in the help menu in the notebook UI.
+ help_links: KernelReply_HelpLink array;
}
type KernelStatus =
@@ -483,7 +521,7 @@ type Header =
type KernelMessage =
{
- Identifiers: list;
+ Identifiers: list;
HmacSignature: string;
Header: Header;
ParentHeader: Header;
diff --git a/src/IfSharp.Kernel/app.config b/src/IfSharp.Kernel/app.config
index bb9b825..3f0d0d2 100644
--- a/src/IfSharp.Kernel/app.config
+++ b/src/IfSharp.Kernel/app.config
@@ -6,6 +6,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/IfSharpConsole/IfSharpConsole.csproj b/src/IfSharpConsole/IfSharpConsole.csproj
index 95d8766..aedd695 100644
--- a/src/IfSharpConsole/IfSharpConsole.csproj
+++ b/src/IfSharpConsole/IfSharpConsole.csproj
@@ -63,9 +63,6 @@
true
-
- ..\..\packages\NetMQ.3.3.0.11\lib\net40\NetMQ.dll
-
@@ -116,6 +113,26 @@
+
+
+
+
+ ..\..\packages\AsyncIO\lib\net35\AsyncIO.dll
+ True
+ True
+
+
+
+
+
+
+ ..\..\packages\AsyncIO\lib\net40\AsyncIO.dll
+ True
+ True
+
+
+
+
@@ -127,4 +144,24 @@
-
+
+
+
+
+ ..\..\packages\NetMQ\lib\net35\NetMQ.dll
+ True
+ True
+
+
+
+
+
+
+ ..\..\packages\NetMQ\lib\net40\NetMQ.dll
+ True
+ True
+
+
+
+
+
\ No newline at end of file
diff --git a/src/IfSharpConsole/Program.cs b/src/IfSharpConsole/Program.cs
index 3760510..2aa7ea0 100644
--- a/src/IfSharpConsole/Program.cs
+++ b/src/IfSharpConsole/Program.cs
@@ -7,6 +7,7 @@ class Program
{
static void Main(string[] args)
{
+ //System.Diagnostics.Debugger.Launch();
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture;
App.Start(args);
diff --git a/tests/IfSharp.Kernel.Tests/IfSharp.Kernel.Tests.fsproj b/tests/IfSharp.Kernel.Tests/IfSharp.Kernel.Tests.fsproj
index cfc2530..31f4e07 100644
--- a/tests/IfSharp.Kernel.Tests/IfSharp.Kernel.Tests.fsproj
+++ b/tests/IfSharp.Kernel.Tests/IfSharp.Kernel.Tests.fsproj
@@ -98,6 +98,26 @@
True
+
+
+
+
+ ..\..\packages\AsyncIO\lib\net35\AsyncIO.dll
+ True
+ True
+
+
+
+
+
+
+ ..\..\packages\AsyncIO\lib\net40\AsyncIO.dll
+ True
+ True
+
+
+
+
@@ -121,6 +141,15 @@
+
+
+
+ ..\..\packages\NetMQ\lib\net35\NetMQ.dll
+ True
+ True
+
+
+