WSTPServer 的介绍

WSTPServer 是一个服务器程序,可以为新收到的 WSTP(Wolfram 符号传输协议)连接启动和维护 Wolfram 语言内核. 该程序侦听单个 WSTP 终端,允许任何数量的客户端连接到已知位置以获取内核.
该程序将所有流量发送到其管理的内核,并允许 WSTPServer 的链接如同直接链接到内核一样表现. 内核可通过内核池的使用配置特定属性. 由于 WSTPServer 内核可以先连接,再断开连接,到再连接,所以你可以维护一个可以从不同程序或机器连接到的长期时域. 简单来说,你可以把 WSTPServer 想成是一个预启动、预配置的 Wolfram 语言内核,代替传统的在需要的时候启动一个新内核的流程.
启动 WSTPServer
WSTPServer 是一个服务器程序,它必须处于运行状态,才能与其相连接.
$ /Applications/Mathematica.app/Contents/SystemFiles/Links/WSTPServer/wstpserver

WSTPServer: Logger (0, 2020-09-29 16:50:00): Information:
    Using "/Applications/Mathematica.app/Contents/MacOS/WolframKernel" as a default kernel path

WSTPServer: Logger (0, 2020-09-29 16:50:05): Information:
    Listening for new connections on port 31415

...
在 Windows 系统中,在 cmd.exe 中运行以下内容可启动 WSTPServer:
$ "C:\Program Files\Wolfram Research\Mathematica\12.2\SystemFiles\Links\WSTPServer\wstpserver.exe"

WSTPServer: Logger (0, 2020-09-29 16:50:00): Information:
    Using "C:\Program Files\Wolfram Research\Mathematica\12.2\wolfram.exe" as a default kernel path

WSTPServer: Logger (0, 2020-09-29 16:50:05): Information:
    Listening for new connections on port 31415

...
在 Linux 系统中,在终端中运行以下内容可启动 WSTPServer:
$ /usr/local/Wolfram/Mathematica/12.2/SystemFiles/Links/WSTPServer/wstpserver

WSTPServer: Logger (0, 2020-09-29 16:50:00): Information:
    Using "/usr/local/Wolfram/Mathematica/12.2/Executables/WolframKernel" as a default kernel path

WSTPServer: Logger (0, 2020-09-29 16:50:05): Information:
    Listening for new connections on port 31415

...
关于上述内容,记住只有 12.2 或之后版本的 Wolfram 语言的设计包含了 wstpserver. 如果你的产品不是 Mathematica,则根据自己产品的情况调整上述路径(如,产品为 Wolfram 桌面).
如果你的终端返回到命令行,则意味着 WSTPServer 已因为无法恢复的问题退出,这样你就不能连接到该服务器. WSTPServer 会将退出的原因记录在你的终端.
WSTPServer 还可以在服务管理系统下运行,如 launchdsystemd 或 Windows Services Manager.
持久化内核
Wolfram 语言内核通常被其与用户的连接所限制:当连接断开时,相关内核也会断开,同时其正在做的所有工作也会停止. 然而,WSTPServer 允许用户在不停止其工作的情况下与内核断开连接,并在之后重新连接到同一个内核.
通过 WSTPServer 连接到内核的其中一个好处是,你可以建立状态(比如,通过加载文件、定义和计算表达式的方式),然后让内核处于活跃状态,这样以后即使是再不同的机器上,你也可以重新连接到内核. 在 "桥接到之前使用过的内核" 章节中会给出范例.
另一个优势是,WSTPServer 可以在受干扰的网络连接状况下阻止内核死机,允许内核继续工作. 网络连接可能很不稳定,有时也无法维护. 为了回到断开连接的内核,用户所需要做的就是重新连接到 WSTPServer 并将其指向连接已经连接丢失的内核.
最后一个范例是关于长时间运算. 用户可以从由在 WSTPServer 管理的内核中进行长时间运算开始,然后当计算预计要完成时,获取结果. 在初始内核忙碌时,用户还可以连接到由 WSTPServer 管理的其他内核并给它们提供任务.
每个内核都有对应的内核 ID 可用于连接到该内核. 这些 ID 可通过在内核中计算 WSTPServer`GetKernelID[] 或使用 GetKernelID WSTP 命令进行获取.
术语 "桥梁" 会在本文档中进场用到. WSTPServer 就像一个中间人,在客户端和内核之间来回通信. 桥梁就是 WSTPServer 在客户端和内核之间建立的连接. "断开桥接" 即断开客户端和内核之间的连接,然后客户端可桥接到另一个内核.
想要了解连接到特定内核的更多信息,请参阅 Wolfram 语言函数 WSTPServer`ConnectKernel 和 WSTP 命令 ConnectKernel 的相关描述.
内核池
内核池是共享用户配置属性,如初始化代码,的一组内核. 大多数由 WSTPServer 管理的内核都是这种池子的成员,且至少有一个内核池子必须设置为默认池. 提供给默认池中的内核的连接不要求特定内核或池. 配置多个内核池允许你对不同的用途目的有不同的预初始化内核.
想要了解更多关于默认池和内核池的配制过程的信息,请参见配置文件章节. 想要了解更多关于连接到特定内核的信息,请参见 Wolfram 语言函数 WSTPServer`ConnectKernel 和 WSTP 命令 ConnectKernel 的描述. 在桥接到特别配制池的章节中给出了一个范例,描述如何使用 WSTPServer`ConnectKernel 桥接到特定内核池.
与多客户端一起使用
Wolfram 系统大都通过使用 WSTP 实现与内核的通信. 因此,WSTPServer 很容易与很多 Wolfram 系统组件集成.
本章节详细描述了如何将 WSTPServer 与多个常用组件一起使用.

与 WolframScript 一起使用

WolframScript 是 Wolfram 语言的一个命令行脚本编译器,可以运行 Wolfram 语言代码、函数和已部署 API. WolframScript 还能连接到 WSTPServer 并与其内核交互.
在下列范例中,WolframScriptWSTPServer 内核中运行代码:
$ wolframscript -wstpserver -code "StringReverse[\"hello\"]"
olleh
WolframScript 允许快速再连接到 WSTPServer 内核. 为了安全达到这个目标,推荐在用户必须管理的文件系统的 profiles 中追溯特定内核的连接情况. WolframScript 在用户参数文件中记录正在使用的内核的 ID,使其可以被重新连接.
想要使用让你可以重新连接到 WSTPServer 内核的用户参数文件,使用 -startprofile 选项:
可以使用 -continueprofile 重新连接到同一个内核并检索 x 的值.
你还可以使用 -wstpserver 连接到特定 WSTPServer. 在此范例中,我们连接到了在端口 31416 监听的在本地端口运行的 WSTPServer.
在没有 WSTPServer 的情况下使用 WolframScript 时,在每次计算时你都会得到一个新的内核. 使用设置了 -startprofile-continueprofileWSTPServer 让你可以在多个 WolframScript 计算中使用相同的内核维护会话.
程序页面 "WolframScript""DETAILS" 会话更详细地描述了用户参数文件和 -wstpserver-startprofile-continueprofile 这些选项. 会话 "OPTIONS" 提供了一个有用的 WolframScript's 命令行选项的高级概览.

与笔记本界面一起使用

下列说明描述了如何将笔记本前端连接到 WSTPServer 和如何与其内核进行交互:
1. 在本地机器上运行前端. 在工具条中,导航到 Evaluation Kernel Configuration Options....
2. 添加一个新的内核并对其进行配置. 在对话框中,点击 Add,然后会出现一个内核配置对话框.
3. 为内核输入一个合适的名称,如 WSTPServerKernel.
4. 选择高级选项的开关. 在名称为 "MLOpen 的参数" 的文本框中,输入下列内容,其中 "port" 和 "host",(可选)应被 WSTPServer 实际监听的端口和主机替代:
5. 点击 OK 并新建一个笔记本.
6. 在工具条上,导航到 Evaluation Notebook's Kernel 并选择你创建的内核名称.
7. 在笔记本内部,验证在由 WSTPServer 管理的内核中计算命令 (e.g. 2+2, WSTPServer`GetKernelID[]) 会生成预期结果.
一些与通过 WSTPServer 使用笔记本界面有关的范例可见章节 "附录:范例场景".

并行计算中的使用

Wolfram 语言为并行计算提供了一个强大而独特的环境. 通常来说,大部分功能可以很轻易使用,并不需要在底层并行系统的内部花太多精力.
WSTPServer 可以管理一个并行内核的池子,供并行计算功能使用. 并行计算功能需要额外配置,这样才可以连接到 WSTPServer 并行内核. 章节使用并行计算功能中给出了一个范例,描述了在前端中使用该功能的过程.
"要配置的内核类型"与 WSTPServer 相关的章节更详细地描述了具有并行计算功能的接口.

在 WSTP C 语言绑定中的使用

所有上述客户端都充分利用了 WSTP,但也隐藏了很多低阶细节. WSTP 为想要将 WSTP 使用到极致的程序员提供了一个 C 绑定.
从你自己的 WSTP 项目中很容易连接到 WSTPServer. WSTP 连接到 WSTPServer 与连接到普通内核的方式几乎一样. 通常来说,WSTPServer 会在客户端连接的时候给客户端发送一些 InputNamePacket. WSTPServer 然后会向内核发送客户端的通信,并向客户端发送内核的通信. 从客户端的角度,似乎是直接链接到内核.
上述描述的一个例外是,WSTPServer 允许将一个命令类别发送给 WSCommandPacket 数据包中的 WSTP 连接. 这些命令被 WSTPServer 拦截并没有发送给内核. 这些命令的描述在章节 "命令语言" 中给出.
下列抽样程序连接到 WSTPServer 并进行运算. 除了打开链接的方式外,这是一个完全标准的 WSTP 程序. 注意调用到 WSOpenString"-linkmode connect -linkname 31415 -linkprotocol TCPIP -linkoptions 4" 规格.
/************************************
    include directives
*************************************/

#include "stdio.h" /* printf */

#include "wstp.h" /* WSENV, WSLINK, WSInitialize, WSOpenArgcArgv, ... */

/************************************
    define directives
*************************************/

#define WSTP_ENVIRONMENT_ERROR 1
#define WSTP_OPEN_ERROR 2
#define WSTP_ACTIVATION_ERROR 3
#define WSTP_INPUTNAMEPACKET_ERROR 4
#define WSTP_GENERAL_ERROR 5

/************************************
    connecting to a link server
*************************************/

/* entry point */
int main(int argc, char **argv)
{
    WSENV env;
    WSLINK link;

    int error;

    /* initialize a WSTP environment */
    env = WSInitialize(NULL);
    if(env == NULL)
    {
        (void) printf("%s\n", "Could not initialize a WSTP environment");
        return WSTP_ENVIRONMENT_ERROR;
    }

    /* open a link to a WSTPServer listening on port 31415 on the local machine */
    link = WSOpenString(env, "-linkmode connect -linkname 31415 -linkprotocol TCPIP -linkoptions 4", &error);
    if(link == NULL || error)
    {
        (void) printf("%s\n", "Could not open a link to WSTPServer");
        return WSTP_OPEN_ERROR;
    }

    /* activate the link to WSTPServer */
    error = WSActivate(link);
    if(!error)
    {
        (void) printf("%s\n", "Could not activate the link to WSTPServer");
        return WSTP_ACTIVATION_ERROR;
    }

    /* receive InputNamePacket packet */
    if(WSNextPacket(link) != INPUTNAMEPKT)
    {
        (void) printf("%s\n", "Could not receive InputNamePacket packet");
        return WSTP_INPUTNAMEPACKET_ERROR;
    }
    (void) WSNewPacket(link);

    /* send over the link:
        EvaluatePacket[2 + 2] */
    if(
        !(
            WSPutFunction(link, "EvaluatePacket", 1) &&
                WSPutFunction(link, "Plus", 2) &&
                    WSPutInteger(link, 2) &&
                        WSPutInteger(link, 2) &&
                            WSFlush(link)
        )
    )
    {
        (void) printf("%s\n", "General WSTP error occurred");
        return WSTP_GENERAL_ERROR;
    }

    /* read off packets until ReturnPacket */
    while(
        (WSNextPacket(link) != RETURNPKT) &&
            (WSError(link) == WSEOK)
    ) { }
    if(WSError(link) != WSEOK)
    {
        (void) printf("%s\n", "General WSTP error occurred");
        return WSTP_GENERAL_ERROR;
    }

    /* clean up */
    (void) WSClose(link);
    (void) WSDeinitialize(env);

    return 0;
}
配置文件
WSTPServer 的行为主要通过 wstpserver.conf 配置文件进行控制.
首先在当前工作目录中搜索配置文件. 若不存在有效的配置文件,则会在应用数据目录中创建一个有默认内容的配置文件.
{
#    Lines that begin with # are comments
#    "AllowStealingKernels":false,
#    "AllowSilentKernelReplacement":false,
#    "EnableAutomaticKernelConnection":false,
#    "SendInputNamePacketUponKernelConnection":true,
    "Pools":
        {
            "KernelPoolOne":
                {
#                    "Default":true,
#                    Only uncomment one of the "KernelPath" lines below
#                    Make sure to change the value to reflect the actual location of your Wolfram kernel binary
#                    "KernelPath":"C:\\Program Files\\Wolfram Research\\Mathematica\\13.2\\wolfram",
#                    "KernelPath":"/usr/local/Wolfram/Mathematica/13.2/Executables/WolframKernel",
#                    "KernelPath":"/Applications/Mathematica.app/Contents/MacOS/WolframKernel",
#                    "InitializationCode":"x=2+2",
#                    "InitializationFile":"/path/to/your/initialization/file.wl",
#                    "KernelOptions":"-yourkerneloption1 -yourkerneloption2",
#                    "KeepAlive":true,
#                    "MinimumKernelNumber":2,
#                    "ParallelKernels":false,
#                    "ReservePreviouslyConnectedKernels":false
                },
#            "KernelPoolTwo":
#                {
#                    "ParallelKernelDefault":true,
#                    "ParallelKernels":true,
#                    Only uncomment one of the "KernelPath" lines below
#                    Make sure to change the value to reflect the actual location of your Wolfram kernel binary
#                    "KernelPath":"C:\\Program Files\\Wolfram Research\\Mathematica\\13.2\\wolfram",
#                    "KernelPath":"/usr/local/Wolfram/Mathematica/13.2/Executables/WolframKernel",
#                    "KernelPath":"/Applications/Mathematica.app/Contents/MacOS/WolframKernel"
#                }
        }
}

键-值数据对

WSTPServer 可识别下列在配置文件中的根密钥:
AllowStealingKernels
true
客户端是否可以用内核 ID 桥接到一个已桥接到另一个客户端的内核
AllowSilentKernelReplacement
false
当桥接内核死机,应在不关闭客户端链接的情况下静静地用一个新内核替换这个死机内核
EnableAutomaticKernelConnection
false
默认池的内核是否应在连接完成后立即与客户端进行桥接,这与只在第一个非 WSCommandPacket 表达式发送给客户端链接时桥接内核的操作不同
Pools
required
要使用的 WSTPServer 的池子列表
SendInputNamePacketUponKernelConnection
true
是否应为在客户端连接后发生的桥接事件发送 InputNamePacket
Pools 中至少需要有一个已命名的内核池,但包含的键-值数据对是可选的,且它们有默认值.
AllowStealingKernels 设置为 true,你可以从一台电脑转换到另一台电脑,并在无需首先在原始电脑上与内核断开桥接的情况下维持同一个内核会话.
AllowSilentKernelReplacement 设置为 true则(例如,由于 KeepAlive 标志变量设为 false 而导致的) WSTPServer 自己关闭的内核不会被替换. 若 AllowSilentKernelReplacementfalse,则当桥接内核死机时,桥接到该内核的客户端链接会被关闭.
如果 EnableAutomaticKernelConnectiontrue,内核将在建立后立即与客户端链接进行桥接. 这可以减少使用客户端链接进行第一次运算所需的时间,因为内核在需要之前已经准备就绪.
WSTPServerPools 内部识别下列内核池的键:
Default
automatic
是否将这个池子作为新客户端的默认池
InitializationCode
""
池子中为内核运行的初始化代码
InitializationFile
""
池子中为内核运行的初始化文件
KernelPath
automatic
池子中的内核会运行的可执行 Wolfram 语言内核的路径
KernelOptions
""
池子中的内核会运行的可执行 Wolfram 语言其他命令行选项
KeepAlive
true
是否无限期保持内核活跃,或在断开桥接时关闭内核
MaximumKernelNumber
automatic
池子可以包含的最大数量的运行内核
MinimumKernelNumber
2
池子会一直保持的最小数量的运行内核
ParallelKernelDefault
automatic
是否将该池子用作并行运算的默认池
ParallelKernels
false
池子的内核是否应为并行运算配置
ReservePreviouslyConnectedKernels
true
是否之前已经桥接的内核仅在通过内核 ID 请求的情况下才能再次桥接
对于第一个内核池对象来说,Default 的自动值为 true.
对于第一个将 ParallelKernels 设置为 true 的池对象而言,ParallelKernelDefault 的自动值为 true.
KernelPath 的自动值是一个自动发现字符串,但是这个自动发现也许会失败;如果失败了,则需要 KernelPath.
MinimumKernelNumber 的值大于 0,则 MaximumKernelNumber 的自动值是 MinimumKernelNumber 的值;否则,该值为 2.
WSTPServer 会预启动数量等于在 MinimumKernelNumber 启动时的值的内核. 这些内核可通过配置文件键 InitializationCodeInitializationFile 进行预热.
KeepAlive 设定为 true,在客户端断开连接时内核不会关闭,并允许其被同一客户端或不同客户端重新连接. 客户端在使用 Wolfram 语言函数 WSTPServer`DisconnectKernelWSTP 命令 DisconnectKernel 而非 QuitExit 时必须小心,这个操作可能会导致内核退出.
ReservePreviouslyConnectedKernelsfalse,则如果存在之前桥接内核的话,按照断开桥接的顺序偏好之前桥接的内核.
命令语言
可通过命令的使用对 WSTPServer 进行动态控制. 命令直接通过 WSTP 连接直接发送到在一个称为 WSCommandPacket 的特殊封装器中的 WSTPServer ;这些命令的结果则发回到 ReturnPacket 数据包. WSCommandPacket 功能存在的目的是给程序员编写自己的 WSTP 程序与 WSTPServer 一起使用. WSCommandPacket 的范例参见章节 "Use with the在 WSTP C 语言绑定中的使用".
命令数据包的结构应该为如下:
    
WSCommandPacket[command[arguments]]
命令数据包返回的数据包结构如下:
    
ReturnPacket[returnvalue]
如果发送的命令数据包的结构不正确,则会返回 ReturnPacket["{\"status\":\"PacketMalformed\"}".
在命令数据包中可能会出现的命令有如下:
CloseKernel
关闭指定内核
ConnectKernel
用指定内核桥接当前连接
ConnectParallelKernel
用在并行内核默认池中第一个可用的内核桥接当前连接
DisconnectKernel
断开当前与其桥接内核的连接
GetKernelBusyStatus
告知桥接到当前连接的内核是否忙于计算
GetKernelID
获取桥接到当前连接的内核的 ID
GetNumberOfAvailableParallelKernels
获取并行内核默认池中可用内核的数量
GetPoolName
获取桥接到当前连接的内核池的名称
GetServerInformation
获取所有池和所有内核的信息
SetAllowSilentKernelReplacement
设置是否允许或禁止内核死机时在不通知的情况下替换桥接到当前连接的内核
SetKeepAlive
设置在当前连接断开或桥接结束时是否关闭桥接到当前连接的内核
SetReserveKernel
设置当断开桥接时,当前内核是否仅可以桥接到通过 ID 请求的客户端
StartKernel
(在任何池子之外)启动一个内核,并返回其 ID
以下子章节详细描述了所有上面给出的 WSTP 命令.

WSTP 命令: CloseKernel

WSCommandPacket[CloseKernel["id"]] 关闭有 id 这样的 ID 的内核.
一旦成功,则返回 ReturnPacket["{\"status\":\"ExecutionSuccess\"}"];若失败了,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"].

WSTP 命令: ConnectKernel

WSCommandPacket[ConnectKernel[]] 用默认池子中的可用内核桥接当前连接. 若内核依然忙于之前桥接客户端的计算,该函数会在等待一个短暂的默认超时时间后失败.
kernelSpecifier 是内核 ID,则 WSCommandPacket[ConnectKernel["kernelSpecifier"]] 用 ID 为 kernelSpecifier 的内核桥接当前连接,若 kernelSpecifier 是内核池名称,则用名称为 kernelSpecifier 的内核池中的可用内核桥接. 若 kernelSpecifier 是内核 ID,则会中止任何用指定内核进行的现存桥接. 若内核忙于之前桥接客户端的计算,则该函数会在等待一个短暂的默认超时时间后失败.
kernelSpecifier 是内核 ID,则 WSCommandPacket[ConnectKernel["kernelSpecifier", timeout]] 用 ID 为 kernelSpecifier 的内核桥接当前连接,若 kernelSpecifier 是内核池名称,则会使用名称为 kernelSpecifier 的内核池中可用内核进行桥接. 若 kernelSpecifier 是内核 ID,则中指任何用指定内核进行的现存桥接. 若内核忙于之前桥接客户端的计算,则该函数会在等待 timeout 秒后失败.
若成功,则返回 ReturnPacket["{\"status\":\"ExecutionSuccess\"}"] ;若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"].

WSTP 命令: ConnectParallelKernel

WSCommandPacket[ConnectParallelKernel[]]用并行内核默认池中的可用内核桥接当前连接. 若内核依然忙于之前桥接的客户端的计算,则该函数会在等待一个短暂的默认超时时间后失败.
WSCommandPacket[ConnectParallelKernel[timeout]] 用并行内核默认池中的可用内核桥接当前连接. 若内核依然忙于之前桥接的客户端的计算,则该函数会在等待 timeout 秒之后失败.
若成功,则返回 ReturnPacket["{\"status\":\"ExecutionSuccess\"}"];若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"].

WSTP 命令: DisconnectKernel

WSCommandPacket[DisconnectKernel[]] 断开当前连接和桥接内核的桥接.
若当前连接未桥接,则 DisconnectKernel 失败.
若成功,则返回 ReturnPacket["{\"status\":\"ExecutionSuccess\"}"];若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"] .

WSTP 命令: GetKernelBusyStatus

WSCommandPacket[GetKernelBusyStatus[]] 可显示桥接到当前连接的内核是否忙于运算. 若当前连接未被桥接,则该函数会失败.
WSCommandPacket[GetKernelBusyStatus["id"]] 可显示有 ID id 的内核是否忙于运算.
若成功,则返回 ReturnPacket["{\"result\":\"True\"}"]ReturnPacket["{\"result\":\"False\"}"];若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"] .

WSTP 命令: GetKernelID

WSCommandPacket[GetKernelID[]] 获取桥接到当前连接的内核 ID.
若当前连接未被桥接,则 GetKernelID 失败.
若成功,则返回 ReturnPacket["{\"result\":\"id\"}"] ;若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"] .

WSTP 命令:GetNumberOfAvailableParallelKernels

WSCommandPacket[GetNumberOfAvailableParallelKernels[]]获取并行内核默认池中可用内核的数量.
若成功,则返回 ReturnPacket["{\"result\":\"num\"}"] ;若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"] . num 的值是并行内核默认池中可用内核的数量.

WSTP 命令:GetPoolName

WSCommandPacket[GetPoolName[]] 获取桥接到当前连接的内核所属池子的名称.
若当前连接未被桥接,或若内核不是池子的一部分,则 GetPoolName 失败.
若成功,则返回 ReturnPacket["{\"result\":\"name\"}"] ;若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"] .

WSTP 命令:GetServerInformation

WSCommandPacket[GetServerInformation[]] 获取所有池子和所有内核的信息.
若成功,则返回 ReturnPacket["json"] ;若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"]. 若成功,则 json 会匹配下面给出的 JSON 架构::
{
    "result":
        {
            # An object containing configured pools and their properties
            "Pools":
                {
                    string: # The name of a particular pool
                        # An object containing the properties of a particular pool and their values
                        {
                            "InitializationCode":string,
                            "InitializationFile":string,
                            "MaximumKernelNumber":number,
                            "MinimumKernelNumber":number,
                            "KeepAlive":Boolean,
                            "EntryPool":Boolean,
                            "KernelPath":string,
                            "PreferFreshKernel":Boolean,
                            "ReservePreviouslyConnectedKernels":Boolean,
                            "ParallelKernels":Boolean,
                            "ParallelKernelEntryPool":Boolean
                        },
                        ...
                }
            }
        }
}
章节 "监控 WSTPServer" 中给出了一个描述使用相似 Wolfram 语言函数 WSTPServer`GetServerInformation 监控 WSTPServer 的范例.

WSTP 命令:SetAllowSilentKernelReplacement

WSCommandPacket[SetAllowSilentKernelReplacement[setting]] 允许或禁止在内核死机时在不通知的情况下重启桥接到当前连接的内核. setting 的值应为 TrueFalse.
若当前连接未桥接,则 SetAllowSilentKernelReplacement 失败. SetAllowSilentKernelReplacement 覆写 AllowSilentKernelReplacement 的关于当前桥接的配置文件键.
若成功,则返回 ReturnPacket["{\"status\":\"ExecutionSuccess\"}"] ;若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"].

WSTP 命令:SetKeepAlive

WSCommandPacket[SetKeepAlive[setting]] 在当前连接断开或桥接结束时指导 WSTPServer 是否关闭桥接到当前连接的内核. setting 的值应为 TrueFalse.
若当前连接未被桥接,则 SetKeepAlive 失败. SetKeepAlive 覆写 KeepAlive 的关于当前桥接的配置文件键.
若成功,则返回 ReturnPacket["{\"status\":\"ExecutionSuccess\"}"] ;若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"] .

WSTP 命令:SetReserveKernel

WSCommandPacket[SetReserveKernel[setting]] 设置在断开桥接时当前内核是否仅可通过请求 ID 的方式桥接到客户端. setting 的值应为 TrueFalse.
若当前连接未被桥接,或内核并非池子的一部分,则 SetReserveKernel 失败. SetReserveKernel 对内核的效果在整个桥接事件过程中一直持续. SetReserveKernel 覆写 ReservePreviouslyConnectedKernels 关于桥接的配置文件键.
若成功,则返回 ReturnPacket["{\"status\":\"ExecutionSuccess\"}"];若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"].

WSTP 命令:StartKernel

WSCommandPacket[StartKernel[](在任何池子之外)启动一个内核,并返回其 ID.
WSCommandPacket[StartKernel["commandLine"]](在任何池子之外)使用 commandLine 启动一个内核,并返回其 ID.
若成功,则返回 ReturnPacket["{\"result\":\"id\"}"];若失败,则返回 ReturnPacket["{\"status\":\"ExecutionError\"}"] .
Wolfram 语言函数
前述章节描述了使用 WSCommandPacket 数据包控制 WSTPServer 的低阶方法. 同时也有一个类似的 Wolfram 语言函数组允许 WSTPServer 内核自身访问和控制.
Wolfram 语言命令如下:
WSTPServer`CloseKernel
关闭指定内核
WSTPServer`ConnectKernel
用指定内核桥接当前连接
WSTPServer`DisconnectKernel
断开当前连接与其桥接内核的桥接
WSTPServer`GetKernelID
获取桥接到当前连接的内核的 ID
WSTPServer`GetPoolName
获取桥接到当前连接的内核所在池的名称
WSTPServer`GetServerInformation
获取所有池子和内核的信息
WSTPServer`SetAllowSilentKernelReplacement
设置是否在内核死机时在不通知的情况下允许或禁止替换内核
WSTPServer`SetKeepAlive
设置在当前连接断开或桥接结束时是否关闭桥接到当前连接的内核
WSTPServer`SetReserveKernel
设置在断开桥接时当前内核是否尽可通过客户端以 ID 请求的方式进行桥接
WSTPServer`StartKernel
(在任意池子之外)启动一个内核,并返回其 ID
以下子章节详细描述了所有上面提到的 Wolfram 语言函数.

Wolfram 语言函数:WSTPServer`CloseKernel

WSTPServer`CloseKernel["id"] 关闭 ID 为 id 的内核.
若成功,则返回一个成功对象;若失败,则返回一个失败对象.

Wolfram 语言函数:WSTPServer`ConnectKernel

WSTPServer`ConnectKernel[] 用默认池中可用的内核桥接当前连接. 若内核依然忙于之前桥接客户端的计算,则函数会等待一个短暂地默认超时时间然后失败.
kernelSpecifier 是内核 ID,则 WSTPServer`ConnectKernel["kernelSpecifier"] 用 ID 为 kernelSpecifier 的内核桥接当前连接,若 kernelSpecifier 是池子名称,则用属于名称为 kernelSpecifier 的池子中的可用内核来桥接当前连接. 若 kernelSpecifier 为内核 ID,则中止任何与指定内核相关的现存桥接. 若内核依然忙于之前桥接客户端的计算,则函数会等待一个短暂地默认超时时间然后失败.
kernelSpecifier 是内核 ID,则 WSTPServer`ConnectKernel["kernelSpecifier", timeout] 用 ID 为 kernelSpecifier 的内核桥接当前连接,若 kernelSpecifier 是池子名称,则用属于名称为 kernelSpecifier 的池子中的可用内核来桥接当前连接. 若 kernelSpecifier 为内核 ID,则中止任何与指定内核相关的现存桥接. 若内核依然忙于之前桥接客户端的计算,则函数会等待 timeout 秒后失败.
若成功,则返回成功对象;若失败,则返回失败对象.

Wolfram 语言函数:WSTPServer`DisconnectKernel

WSTPServer`DisconnectKernel[] 断开当前连接与其桥接内核的桥接.
若当前连接未被桥接,则 WSTPServer`DisconnectKernel 失败.
若成功,则返回成功对象;若失败,则返回失败对象.

Wolfram 语言函数:WSTPServer`GetKernelID

WSTPServer`GetKernelID[] 获取桥接到当前连接的内核的 ID.
若当前连接未被桥接,则 WSTPServer`GetKernelID 失败.
若成功,则返回 "id";若失败,则返回失败对象.

Wolfram 语言函数:WSTPServer`GetPoolName

WSTPServer`GetPoolName[] 获取桥接到当前连接的内核所属池子的名称.
若内核不是池子的一部分,或若当前连接没有桥接,则 WSTPServer`GetPoolName 会失败.
若成功,则返回 "name";若失败,则返回失败对象.

Wolfram 语言函数:WSTPServer`GetServerInformation

WSTPServer`GetServerInformation[] 获取所有池子和所有内核的信息.
若成功,则返回与章节 "监控 WSTPServer" 中提到的 JSON 架构类似的 Association;若失败,则返回失败对象.
章节 "监控 WSTPServer" 给出了一个描述类似 Wolfram 语言函数 WSTPServer`GetServerInformation in 监控 WSTPServer 的范例.

Wolfram 语言函数:WSTPServer`SetAllowSilentKernelReplacement

若内核死机,WSTPServer`SetAllowSilentKernelReplacement[setting] 可允许或禁止在不通知的情况下重启桥接到当前连接的内核. setting 的值应为 TrueFalse.
若当前连接没有被桥接,则 WSTPServer`SetAllowSilentKernelReplacement 失败. WSTPServer`SetAllowSilentKernelReplacement 覆写 AllowSilentKernelReplacement 与当前桥接相关的配置文件键.
若成功,则返回成功对象;若失败,则返回失败对象.

Wolfram 语言函数:WSTPServer`SetKeepAlive

在断开桥接时,WSTPServer`SetKeepAlive[setting] 可设定是否当前内核只能通过客户端请求其 ID 进行桥接. setting 的值应为 TrueFalse.
如果当前连接未被桥接,或内核不是池子的一部分,则WSTPServer`SetKeepAlive 失败. WSTPServer`SetKeepAlive 对内核的效果在整个桥接事件中一直持续. WSTPServer`SetKeepAlive 覆写 KeepAlive 关于桥接的配置文件键.
若成功,则返回成功对象;若失败,则返回失败对象.

Wolfram 语言函数:WSTPServer`SetReserveKernel

跟着布尔值 settingWSTPServer`SetReserveKernel[setting] 可设置在断开桥接时是否只有请求其 ID 的客户端才可以桥接到当前内核.
若当前连接未被桥接,或若桥接到当前连接的内核并非池子的一部分,则 WSTPServer`SetReserveKernel 失败. WSTPServer`SetReserveKernel 对内核的效果会在未来桥接事件中一直持续. WSTPServer`SetReserveKernel 覆写内核的配置文件中的 ReservePreviouslyConnectedKernels 键.
若成功,则返回成功对象;若失败,则返回失败对象.

Wolfram 语言函数:WSTPServer`StartKernel

WSTPServer`StartKernel[] (在任何池子外)启动一个内核,并返回其 ID.
WSTPServer`StartKernel["commandLine"] 使用 commandLine,(在任何池子外)启动一个内核,并返回其 ID.
若成功,则返回 "id";若失败,则返回失败对象.
附录:命令行选项
WSTPServer 的命令行选项如下:
-h, --help
打印帮助文本
-l, --log-level n
指定信息的冗长水平
-f, --log-file [file]
给指定文件撰写信息
-a, --advertise [service]
若出现,则将链接服务器通知为指定服务
-p, --port port
监听指定端口
-i, --interface interface
监听指定界面
-c, --configuration-file file
使用指定配置文件
--log-level-l 的冗长程度的三个水平如下:
error, 1
报告服务器启动/关机错误并打印成功启动的信息
debug, 2
报告第一层的所有内容和所有排除故障信息
trace, 3
报告第二层的所有内容和所有已处理 WSTP 流量
若未使用 --log-level-l,则默认日志冗长水平设为 error.
若未使用 --log-file-f,或在未指定文件的情况下使用,信息会被写到 stdout.
若使用了
--advertise [service]
-a [service]
,则 WSTPServer 会尝试将将自身通知为
WSTPServer-Instance
WSTPServer-Instance-service
,取决于 service 是否被指定. WSTPServer 会记录其通知对象的服务名称.
若未使用 --advertise-a,则不会通知其链接服务器.
若未使用 --port -p,则链接服务器会监听端口 31415.
若未使用 --interface-i,则链接服务器会监听默认网络界面. 将界面设置为 localhost 使得 WSTPServer 在本地网络上不可见.
若未使用 --configuration-file-c,则链接服务器会使用默认配置文件搜索行为和使用量.
附录:范例场景

利用并行计算功能

WSTPServer 可以通过 Wolfram 语言并行计算功能管理一个并行内核池.
以下说明展示了如何通过使用前端的 WSTPServer 利用并行计算功能:
1. 确保使用 wstpserver.conf 配置文件配置并行内核.
# wstpserver.conf: place in the current working directory
{
    "Pools":
        {
            "IProvideParallelKernels":
                {
                    "Parallel":true,
                    "MinimumKernelNumber":4
                }
        }
}
2. 在笔记本内部,运行 Needs["WSTPServerTools`"].
3. 用 AppendToConfiguredKernels["port@hostname", num]WSTPServer 并行内核添加到并行计算功能. 第一个参数描述的是 WSTPServer 连接到的端口和主机名称(可选). 第二个参数描述的是要使用的 WSTPServer 并行内核的数量.
4. 运行一些可以利用并行计算功能的代码(如,ParallelSum[EulerPhi[i], {i, 10^6}].
5. 可选情况下,检查配制好的 WSTPServer 并行内核在第三步成功连接上 Kernels[].

桥接到特别配置池

WSTPServer 允许因特别原因配置池子(比如:通过使用共享初始化文件). 在不是默认池子的情况下,会要求通过命令语言来使用这样的池子. 可以使用 Wolfram 语言函数 WSTPServer`ConnectKernelWSTP 命令 ConnectKernel 来桥接到池子.
下列说明演示了如何使用 WolframScript 桥接到特别配置的池子:
1. 确保使用 wstpserver.conf 配置文件来配置池子.
# wstpserver.conf: place in the current working directory
{
    "Pools":
        {
            "IDefineX":
                {
                    "InitializationCode":"x=4"
                }
        }
}
2. 使用控制台,运行 wolframscript -wstpserver -startprofile. 若不能发现 WSTPServer,则使用 -wstpserver wstpserverbase 选项.
3. 在 WolframScript REPL 中,使用 WSTPServer`GetPoolName[] 选择性地验证当前被桥接的内核所在的池子. 注意在给定池子初始化代码的情况下,x 和预期一样计算为 4.
$ wolframscript -wstpserver -kernelpool AlternativeThree

In[1]:= WSTPServer`GetPoolName[]

Out[1]= IDefineX

In[2]:= x

Out[2]= 4

In[3]:=

桥接到之前使用过的内核

在建立好状态后,返回到之前使用过的内核是很有用的. 通常情况下,这会要求使用配置文件键 KeepAliveWSTPServer 配置为永久保持活跃状态. 也会需要 Wolfram 语言函数 WSTPServer`ConnectKernelWSTP 命令 ConnectKernel.
下列说明展示了如何在内核中建立状态,然后使用 WolframScript 返回到该内核:
1. 使用 wstpserver.conf 配置文件确保将内核配置为可以永久保持活跃的状态.
# wstpserver.conf: place in the current working directory
{
    "Pools":
        {
            "IBuildUpState":
                {
                    "KeepAlive":true
                }
        }
}
2. 使用控制台,运行 wolframscript -wstpserver -startprofile. 若不能发现 WSTPServer,则使用 -wstpserver wstpserverbase 选项.
3. 在 WolframScript REPL 中,使用 WSTPServer`GetKernelID[] 获取当前内核 ID 的 ID. 结果很重要:这让我们以后可以返回到当前内核.
$ wolframscript -wstpserver -startprofile

In[1]:= WSTPServer`GetKernelID[]

Out[1]= a806-2645-9651

In[2]:=
4. 下定义并建立状态.
5. 使用 WSTPServer`DisconnectKernel[] 安全断开桥接并断开与 WSTPServer 的连接.
In[10]:= WSTPServer`DisconnectKernel[]
$
6. 为了返回在步骤 2 中获取的内核,运行 wolframscript -wstpserver -continueprofile.
7. 使用 WSTPServer`GetKernelID[] 有选择性地验证当前被桥接的内核的 ID.
$ wolframscript -wstpserver -continueprofile

In[11]:= WSTPServer`GetKernelID[]

Out[11]= a806-2645-9651

In[12]:=

使用 WolframScript 配置文件系统

WolframScript 允许快速重新连接到 WSTPServer 内核. 推荐在用户必须管理的配置文件中追溯到对特定内核的连接. WolframScript 在配置文件中记录正在使用的内核的 ID,以便允许重新连接到该内核.
程序页面 "WolframScript" 中的 "详细信息" 章节详细描述了配置文件系统,以及 -wstpserver, -startprofile-continueprofile 这些选项. 章节 "选项" 提供了一个有用的高阶 WolframScript 命令行选项概览.
下列说明展示了如何使用 WolframScript 桥接到有特定属性的内核:
1. 使用 wstpserver.conf 配置文件确保配置一个有指定属性的内核.
# wstpserver.conf: place in the current working directory
{
    "Pools":
        {
                "IHaveSpecificProperties":
                {
                    "KeepAlive":true,
                    "ReservePreviouslyConnectedKernels":false
                }
        }
}
2. 创建一个包含指定属性的 WSTPServer 内核.
# sampleprofile
KEEPALIVE=TRUE # I want a kernel with "KeepAlive" set to true
RESERVE=TRUE # I want a kernel with "ReservePreviouslyConnectedKernels" set to false
3. 使用控制台,运行 wolframscript -wstpserver -startprofile sampleprofile. 若不能发现 WSTPServer,则使用 -wstpserver wstpserverbase 选项.
$ wolframscript -wstpserver -startprofile sampleprofile

In[1]:=
4. 在 WolframScript REPL 中,下定义并建立状态.
In[1]:= x = 2 + 2

Out[1]:= 4
5. 安全断开桥接并用 WSTPServer`DisconnectKernel[] 断开与 WSTPServer 的连接.
In[10]:= WSTPServer`DisconnectKernel[]
$
6. 为了返回到第 3 步获取的内核,运行 wolframscript -wstpserver -continueprofile sampleprofile.
$ wolframscript -wstpserver -continueprofile sampleprofile

In[11]:= x

Out[11]:= 4

在与和配置相反的 WSTPServer 断开连接后保持内核活跃

通常情况下,在与 WSTPServer 断开连接后想要保持内核活跃则需要 WSTPServer 配置为将配置文件键 KeepAlive 设置为 true,但 Wolfram 语言函数 WSTPServer`SetKeepAliveWSTP 命令 SetKeepAlive 可以永久保持当前桥接的内核活跃.
下列说明展示了如何在就算断开与 WSTPServer`SetKeepAlive,的桥接后保持内核活跃,并用 WolframScript 返回到该内核:
1. 使用 WSTPServer 内核配置 创建笔记本.
2. 在笔记本内部,使用 WSTPServer`GetKernelID[] 获取当前内核 ID 的 ID. 结果是很重要的:会让您可以在以后返回到当前内核.
3. 安全使用 WSTPServer`DisconnectKernel[] WSTPServer 断开桥接和连接.
4. 通过 wolframscript -wstpserver -continueprofile 返回到该内核. 若不能发现 WSTPServer,则使用 -wstpserver port@host 选项.
5. 在 WolframScript REPL 内部,使用 WSTPServer`GetKernelID[] 选择性地验证当前被桥接的内核的 ID.
$ wolframscript -wstpserver -continueprofile

In[11]:= WSTPServer`GetKernelID[]

Out[11]= 825c-6cbd-129b

In[12]:=

保留一个有重要工作的内核

在断开桥接的情况下,仅允许通过客户端请求 ID 的方式才能桥接到客户端的功能是很重要的. 这会使得该内核仅供指定需要的用户使用,且这会让不需要这个指定内核的用户无法访问该内核对话. 若配置文件键 ReservePreviouslyConnectedKernels 设置为 true 则上述为默认行为.
Wolfram 语言函数 WSTPServer`SetReserveKernelWSTP 命令 SetReserveKernel 允许在无论 ReservePreviouslyConnectedKernels 的值是多少的情况下都保留当前内核. 下列说明演示了如何使用 WSTPServer`SetReserveKernel 和前端成功保留并安全与内核断开桥接:
1. 使用 WSTPServer 内核配置创建笔记本.
2. 在笔记本内部,保留有 WSTPServer`SetReserveKernel[True] 的内核.
3. 使用 WSTPServer`DisconnectKernel[] 安全与 WSTPServer 断开桥接和连接.

监控 WSTPServer

WSTPServer 是一个服务器程序,所以检查其当前状态并获取诊断信息会很有用. 为此提供了 Wolfram 语言函数 WSTPServer`GetServerInformation WSTP 命令 GetServerInformation 的功能.
下列说明展示了如何使用前端获取 WSTPServer 的当前状态:
1. 使用 WSTPServer 内核配置 创建笔记本.
2. 在笔记本内部,使用 WSTPServer`GetServerInformation[] 获取 WSTPServer 的当前状态.