对于一个规则引擎中的脚本代码编辑器是非常关键的,因为UI控件直接使用对象是规则维护者,关系到用户体验,在选用脚本编辑器的功能时除了满足代码的编辑的基本编辑要求外,功能还需要包含;语法着色,错误提示,代码格式化,代码折叠,自动代码提示,自动补全代码等功能.(目前技术无法做到JS加断点;边调试边运行)

经过众多开源产品的代码编辑器对比与功能测试,ICSharpCode.TextEditor 是JS脚本编辑器最佳选择.

一.语法着色

JS语法着色XML,对JS关键字进行着色,并可以扩展自指定义关键字着色,

应用场影:规则引擎中新增加函数或变量等关键字时, 为用户体验更好,可增加自定义关键字着色;

例:BoardThick 是关键字,那么在JS代码中,以高亮着色加以区分

<?xml version="1.0"?>
<!-- syntaxdefinition for JavaScript 2.0 by Svante Lidman --> <SyntaxDefinition name ="JavaScript" extensions = ".js"> <Properties>
<Property name="LineComment" value="//"/>
</Properties> <Digits name ="Digits" bold ="false" italic ="false" color ="DarkBlue"/> <RuleSets>
<RuleSet ignorecase = "false">
<Delimiters>=!&gt;&lt;+-/*%&amp;|^~.}{,;][?:</Delimiters> <Span name ="LineComment" bold ="false" italic ="false" color ="DarkSlateGray" stopateol ="true">
<Begin>//</Begin>
</Span> <Span name ="BlockComment" bold ="false" italic ="false" color ="DarkSlateGray" stopateol ="false">
<Begin>/*</Begin>
<End>*/</End>
</Span> <Span name ="String" bold ="false" italic ="false" color ="Sienna" stopateol ="false" escapecharacter="\">
<Begin>&quot;</Begin>
<End>&quot;</End>
</Span> <Span name = "Character" bold = "false" italic = "false" color = "Sienna" stopateol = "true" escapecharacter="\">
<Begin>&apos;</Begin>
<End>&apos;</End>
</Span> <KeyWords name ="JavaScriptKeyWords" bold="false" italic = "false" color = "Blue">
<Key word = "break" />
<Key word = "continue" />
<Key word = "delete" />
<Key word = "else" />
<Key word = "for" />
<Key word = "function" />
<Key word = "if" />
<Key word = "in" />
<Key word = "new" />
<Key word = "return" />
<Key word = "this" />
<Key word = "typeof" />
<Key word = "var" />
<Key word = "void" />
<Key word = "while" />
<Key word = "with" />
<!--ECMAScript keywords-->
<!-- Reserved for future use
(some are already used in some Javascript Engines)
-->
<Key word = "abstract" />
<Key word = "boolean" />
<Key word = "byte" />
<Key word = "case" />
<Key word = "catch" />
<Key word = "char" />
<Key word = "class" />
<Key word = "const" />
<Key word = "debugger" />
<Key word = "default" />
<Key word = "do" />
<Key word = "double" />
<Key word = "enum" />
<Key word = "export" />
<Key word = "extends" />
<Key word = "final" />
<Key word = "finally" />
<Key word = "float" />
<Key word = "goto" />
<Key word = "implements" />
<Key word = "import" />
<Key word = "instanceof" />
<Key word = "int" />
<Key word = "interface" />
<Key word = "long" />
<Key word = "native" />
<Key word = "package" />
<Key word = "private" />
<Key word = "protected" />
<Key word = "public" />
<Key word = "short" />
<Key word = "static" />
<Key word = "super" />
<Key word = "switch" />
<Key word = "synchronized" />
<Key word = "throw" />
<Key word = "throws" />
<Key word = "transient" />
<Key word = "try" />
<Key word = "volatile" />
</KeyWords> <KeyWords name ="JavaScriptIntrinsics" bold="false" italic = "false" color = "Blue">
<Key word = "Array" />
<Key word = "Boolean" />
<Key word = "Date" />
<Key word = "Function" />
<Key word = "Global" />
<Key word = "Math" />
<Key word = "Number" />
<Key word = "Object" />
<Key word = "RegExp" />
<Key word = "String" />
</KeyWords> <KeyWords name ="JavaScriptLiterals" bold="false" italic = "false" color = "Blue">
<Key word = "false" />
<Key word = "null" />
<Key word = "true" />
<Key word = "NaN" />
<Key word = "Infinity" />
</KeyWords> <KeyWords name ="JavaScriptLiterals" bold="false" italic = "false" color = "Blue">
<Key word = "" />
</KeyWords> <KeyWords name ="JavaScriptGlobalFunctions" bold="false" italic = "false" color = "Blue">
<Key word = "eval" />
<Key word = "parseInt" />
<Key word = "parseFloat" />
<Key word = "escape" />
<Key word = "unescape" />
<Key word = "isNaN" />
<Key word = "isFinite" />
</KeyWords> <KeyWords name ="JavaScriptUserFunctions" bold="false" italic = "false" color = "Blue">
<Key word = "console" />
<Key word = "JSON" />
<Key word = "console.log" />
<Key word = "console.alert" />
<Key word = "console.prompt" />
<Key word = "console.print" />
</KeyWords> </RuleSet>
</RuleSets> </SyntaxDefinition>

再来一个C#语法着色 XML供参考

<?xml version="1.0"?>
<!-- syntaxdefinition for C# 2000 by Mike Krueger --> <SyntaxDefinition name = "C#" extensions = ".cs"> <Environment>
<Custom name="TypeReference" bold="false" italic="false" color="#04ABAB" />
<Custom name="UnknownEntity" bold="false" italic="false" color="#AB0404" />
</Environment> <Properties>
<Property name="LineComment" value="//"/>
</Properties> <Digits name = "Digits" bold = "false" italic = "false" color = "DarkBlue"/> <RuleSets>
<RuleSet ignorecase="false">
<Delimiters>&amp;&lt;&gt;~!%^*()-+=|\#/{}[]:;"' , .?</Delimiters> <Span name = "PreprocessorDirectives" rule = "PreprocessorSet" bold="false" italic="false" color="Green" stopateol = "true">
<Begin>#</Begin>
</Span> <Span name = "DocLineComment" rule = "DocCommentSet" bold = "false" italic = "false" color = "Green" stopateol = "true" noescapesequences="true">
<Begin bold = "false" italic = "false" color = "Gray">///@!/@</Begin>
</Span> <Span name = "LineComment" rule = "CommentMarkerSet" bold = "false" italic = "false" color = "Green" stopateol = "true">
<Begin>//@!/@</Begin>
</Span>
<Span name = "LineComment2" rule = "CommentMarkerSet" bold = "false" italic = "false" color = "Green" stopateol = "true">
<Begin>////</Begin>
</Span> <Span name = "BlockComment" rule = "CommentMarkerSet" bold = "false" italic = "false" color = "Green" stopateol = "false">
<Begin>/*</Begin>
<End>*/</End>
</Span> <Span name = "String" bold = "false" italic = "false" color = "Blue" stopateol = "true" escapecharacter="\">
<Begin>"</Begin>
<End>"</End>
</Span> <Span name = "MultiLineString" bold = "false" italic = "false" color = "Blue" stopateol = "false" escapecharacter='"'>
<Begin>@@"</Begin>
<End>"</End>
</Span> <Span name = "Char" bold = "false" italic = "false" color = "Magenta" stopateol = "true" escapecharacter="\">
<Begin>&apos;</Begin>
<End>&apos;</End>
</Span> <MarkPrevious bold = "true" italic = "false" color = "MidnightBlue">(</MarkPrevious> <KeyWords name = "Punctuation" bold = "false" italic = "false" color = "DarkGreen">
<Key word = "?" />
<Key word = "," />
<Key word = "." />
<Key word = ";" />
<Key word = "(" />
<Key word = ")" />
<Key word = "[" />
<Key word = "]" />
<Key word = "{" />
<Key word = "}" />
<Key word = "+" />
<Key word = "-" />
<Key word = "/" />
<Key word = "%" />
<Key word = "*" />
<Key word = "&lt;" />
<Key word = "&gt;" />
<Key word = "^" />
<Key word = "=" />
<Key word = "~" />
<Key word = "!" />
<Key word = "|" />
<Key word = "&amp;" />
</KeyWords> <KeyWords name = "AccessKeywords" bold="true" italic="false" color="Black">
<Key word = "this" />
<Key word = "base" />
</KeyWords> <KeyWords name = "OperatorKeywords" bold="true" italic="false" color="DarkCyan">
<Key word = "as" />
<Key word = "is" />
<Key word = "new" />
<Key word = "sizeof" />
<Key word = "typeof" />
<Key word = "true" />
<Key word = "false" />
<Key word = "stackalloc" />
</KeyWords> <KeyWords name = "SelectionStatements" bold="true" italic="false" color="Blue">
<Key word = "else" />
<Key word = "if" />
<Key word = "switch" />
<Key word = "case" />
<Key word = "default" />
</KeyWords> <KeyWords name = "IterationStatements" bold="true" italic="false" color="Blue">
<Key word = "do" />
<Key word = "for" />
<Key word = "foreach" />
<Key word = "in" />
<Key word = "while" />
</KeyWords> <KeyWords name = "JumpStatements" bold="false" italic="false" color="Navy">
<Key word = "break" />
<Key word = "continue" />
<Key word = "goto" />
<Key word = "return" />
</KeyWords> <KeyWords name = "ContextKeywords" bold="false" italic="false" color="Navy">
<Key word = "yield" />
<Key word = "partial" />
<Key word = "global" />
<Key word = "where" />
<Key word = "select" />
<Key word = "group" />
<Key word = "by" />
<Key word = "into" />
<Key word = "from" />
<Key word = "ascending" />
<Key word = "descending" />
<Key word = "orderby" />
<Key word = "let" />
<Key word = "join" />
<Key word = "on" />
<Key word = "equals" />
<Key word = "var" />
</KeyWords> <KeyWords name = "ExceptionHandlingStatements" bold="true" italic="false" color="Teal">
<Key word = "try" />
<Key word = "throw" />
<Key word = "catch" />
<Key word = "finally" />
</KeyWords> <KeyWords name = "CheckedUncheckedStatements" bold="true" italic="false" color="DarkGray">
<Key word = "checked" />
<Key word = "unchecked" />
</KeyWords> <KeyWords name = "UnsafeFixedStatements" bold="false" italic="false" color="Olive">
<Key word = "fixed" />
<Key word = "unsafe" />
</KeyWords> <KeyWords name = "ValueTypes" bold="true" italic="false" color="Red">
<Key word = "bool" />
<Key word = "byte" />
<Key word = "char" />
<Key word = "decimal" />
<Key word = "double" />
<Key word = "enum" />
<Key word = "float" />
<Key word = "int" />
<Key word = "long" />
<Key word = "sbyte" />
<Key word = "short" />
<Key word = "struct" />
<Key word = "uint" />
<Key word = "ushort" />
<Key word = "ulong" />
</KeyWords> <KeyWords name = "ReferenceTypes" bold="false" italic="false" color="Red">
<Key word = "class" />
<Key word = "interface" />
<Key word = "delegate" />
<Key word = "object" />
<Key word = "string" />
</KeyWords> <KeyWords name = "Void" bold="false" italic="false" color="Red">
<Key word = "void" />
</KeyWords> <KeyWords name = "ConversionKeyWords" bold="true" italic="false" color="Pink">
<Key word = "explicit" />
<Key word = "implicit" />
<Key word = "operator" />
</KeyWords> <KeyWords name = "MethodParameters" bold="true" italic="false" color="DeepPink">
<Key word = "params" />
<Key word = "ref" />
<Key word = "out" />
</KeyWords> <KeyWords name = "Modifiers" bold="false" italic="false" color="Brown">
<Key word = "abstract" />
<Key word = "const" />
<Key word = "event" />
<Key word = "extern" />
<Key word = "override" />
<Key word = "readonly" />
<Key word = "sealed" />
<Key word = "static" />
<Key word = "virtual" />
<Key word = "volatile" />
</KeyWords> <KeyWords name = "AccessModifiers" bold="true" italic="false" color="Blue">
<Key word = "public" />
<Key word = "protected" />
<Key word = "private" />
<Key word = "internal" />
</KeyWords> <KeyWords name = "NameSpaces" bold="true" italic="false" color="Green">
<Key word = "namespace" />
<Key word = "using" />
</KeyWords> <KeyWords name = "LockKeyWord" bold="false" italic="false" color="DarkViolet">
<Key word = "lock" />
</KeyWords> <KeyWords name = "GetSet" bold="false" italic="false" color="SaddleBrown">
<Key word = "get" />
<Key word = "set" />
<Key word = "add" />
<Key word = "remove" />
</KeyWords> <KeyWords name = "Literals" bold="true" italic="false" color="Black">
<Key word = "null" />
<Key word = "value" />
</KeyWords>
</RuleSet> <RuleSet name = "CommentMarkerSet" ignorecase = "false">
<Delimiters>&lt;&gt;~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters>
<KeyWords name = "ErrorWords" bold="true" italic="false" color="Red">
<Key word = "TODO" />
<Key word = "FIXME" />
</KeyWords>
<KeyWords name = "WarningWords" bold="true" italic="false" color="#EEE0E000">
<Key word = "HACK" />
<Key word = "UNDONE" />
</KeyWords>
</RuleSet> <RuleSet name = "DocCommentSet" ignorecase = "false">
<Delimiters>&lt;&gt;~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters> <Span name = "XmlTag" rule = "XmlDocSet" bold = "false" italic = "false" color = "Gray" stopateol = "true">
<Begin>&lt;</Begin>
<End>&gt;</End>
</Span> <KeyWords name = "ErrorWords" bold="true" italic="false" color="Red">
<Key word = "TODO" />
<Key word = "FIXME" />
</KeyWords> <KeyWords name = "WarningWords" bold="true" italic="false" color="#EEE0E000">
<Key word = "HACK" />
<Key word = "UNDONE" />
</KeyWords>
</RuleSet> <RuleSet name = "PreprocessorSet" ignorecase="false">
<Delimiters>&amp;&lt;&gt;~!%^*()-+=|\#/{}[]:;"' , .?</Delimiters> <KeyWords name = "PreprocessorDirectives" bold="true" italic="false" color="Green">
<Key word = "if" />
<Key word = "else" />
<Key word = "elif" />
<Key word = "endif" />
<Key word = "define" />
<Key word = "undef" />
<Key word = "warning" />
<Key word = "error" />
<Key word = "line" />
<Key word = "region" />
<Key word = "endregion" />
<Key word = "pragma" />
</KeyWords>
</RuleSet> <RuleSet name = "XmlDocSet" ignorecase = "false">
<Delimiters>&lt;&gt;~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters> <Span name = "String" bold = "true" italic = "false" color = "Silver" stopateol = "true">
<Begin>"</Begin>
<End>"</End>
</Span> <KeyWords name = "Punctuation" bold = "true" italic = "false" color = "Gray">
<Key word = "/" />
<Key word = "|" />
<Key word = "=" />
</KeyWords> <KeyWords name = "SpecialComment" bold="true" italic="false" color="Gray">
<Key word = "c" />
<Key word = "code" />
<Key word = "example" />
<Key word = "exception" />
<Key word = "list" />
<Key word = "para" />
<Key word = "param" />
<Key word = "paramref" />
<Key word = "permission" />
<Key word = "remarks" />
<Key word = "returns" />
<Key word = "see" />
<Key word = "seealso" />
<Key word = "summary" />
<Key word = "value" />
<Key word = "inheritdoc" /> <Key word = "type" />
<Key word = "name" />
<Key word = "cref" />
<Key word = "item" />
<Key word = "term" />
<Key word = "description" />
<Key word = "listheader" />
</KeyWords>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

二.错误提示

在测试JS代码时,点击运行JS,当报错时直接定位执行JS代码的异常代码.

            string result = "";
string resultType = "";
try
{
var resultJS = context.Run(jsCode);
if (resultJS == null)
{
result = "null";
resultType = "null";
}
else
{
resultType = resultJS.GetType().ToString();
result = Newtonsoft.Json.JsonConvert.SerializeObject(resultJS);
}
}
catch (Exception ex)
{
string CodeLine = "";
if (ex.Data.Contains("V8SourceLine"))
{
var ErrCode = ex.Data["V8SourceLine"];
if (ErrCode != null)
{
CodeLine = CodeLine + "\r\n错误定位代码\r\n" + ErrCode.ToString().Trim(); ;
}
}
MessageBox.Show("报错内容:\r\n" + ex.Message + CodeLine, "JavaScript提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

三.代码格式化

ICSharpCode.TextEditor 控件中没有现成的,这里跟据{}扩号,多层嵌套加首空格的方式进行代码格式化功能

       /// <summary>
/// 格式化JS代码
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
public static string FormatJSCode(string code)
{
//去除空白行
code = RemoveEmptyLines(code);
StringBuilder sb = new StringBuilder();
int count = ;
int times = ;
string[] lines = code.Split('\n');
foreach (var line in lines)
{
if (line.TrimStart().StartsWith("{") || line.TrimEnd().EndsWith("{"))
{
sb.Append(Indent(count * times) + line.TrimStart() + "\r\n");
times++; }
else if (line.TrimStart().StartsWith("}"))
{
times--;
if (times <= )
{
times = ;
}
sb.Append(Indent(count * times) + line.TrimStart() + "\r\n");
}
else
{
sb.Append(Indent(count * times) + line.TrimStart() + "\r\n");
}
}
return sb.ToString();
}

四.补全扩号{} ()[]

当用户敲左扩号时,自动补充右扩号,并将光标点移到2个扩号中间.

       private void txtContent_TextChanged(object sender, EventArgs e)
{
txtContent.Document.FoldingManager.UpdateFoldings(null, null);
if (txtContent.Text.Length <= oldJScodeLength) return;
var Line = this.txtContent.ActiveTextAreaControl.Caret.Line;
var offset = this.txtContent.ActiveTextAreaControl.Caret.Offset;
if (offset == ) return;
var LineSegment = txtContent.ActiveTextAreaControl.TextArea.Document.GetLineSegment(Line);
if (offset == LineSegment.Length) return;
try
{
var charT = txtContent.ActiveTextAreaControl.TextArea.Document.GetText(offset, );
var charE = "";
switch (charT)
{
case "{" :
charE = "}";
break;
case "(":
charE = ")";
break;
case "[":
charE = "]";
break;
}
if (!string.IsNullOrEmpty(charE))
{
txtContent.ActiveTextAreaControl.SelectionManager.RemoveSelectedText();
txtContent.ActiveTextAreaControl.Caret.Column = txtContent.ActiveTextAreaControl.Caret.Column + ;
txtContent.ActiveTextAreaControl.TextArea.InsertChar(charE[]);
txtContent.ActiveTextAreaControl.Caret.Column = txtContent.ActiveTextAreaControl.Caret.Column - ;
this.txtContent.ActiveTextAreaControl.TextArea.ScrollToCaret();
}
}
catch (Exception)
{ }
}

五. 当前光标信息

当前光标所在行,列,所选字符数,基本功能扩展,

        private void JSPositionChanged(object sender, EventArgs e)
{
ICSharpCode.TextEditor.Caret CaretPosition = (ICSharpCode.TextEditor.Caret)sender;
toolStripStatusLabel1.Text = $@"行:{CaretPosition.Line + 1} 列:{CaretPosition.Column + 1} 偏移:{CaretPosition.Offset + 1}";
toolStripStatusLabel3.Text = CaretPosition.CaretMode.ToString();
} private void JSSelectionChanged(object sender, EventArgs e)
{
SelectionManager selContent = (SelectionManager)sender;
toolStripStatusLabel2.Text = $@"选中字符数:{selContent.SelectedText.Length}";
btnRunJSselect.Enabled = selContent.SelectedText.Length > ;
}

PCB 规则引擎之编辑器(语法着色,错误提示,代码格式化)的更多相关文章

  1. javascript 语法规范错误提示代码

    “Missing semicolon.” : “缺少分号.”, “Use the function form of \”use strict\”.” : “使用标准化定义function.”, “Un ...

  2. js eslint语法规范错误提示代码

    最近在用eslint代码检测,因为之前不太注意代码规范,刚开始确实头疼,哈哈,不过用习惯了就会感觉还不错,其实也没有那样难调试 我看过之前有些人已经做过总结,自己记录下,方便自己以后查找 “Missi ...

  3. PCB 围绕CAM自动化,打造PCB规则引擎

    AutoCAM自动化平台,前端管理订单,而后端执行任务,前端UIl界面有板厚,铜厚,板材,表面处理,层数等信息,而这些信息并不是后端最终所需要的信息后.拿钻孔补偿来说,后端需要的是钻孔补偿值,但前端并 ...

  4. PCB 规则引擎之脚本语言JavaScript应用评测

    世界上没有好做的软件,觉得好做,只是你的系统简单而已,而不是哪个行业简单,特别像我们PCB制造企业务逻辑的很复杂的,仅仅靠决策树中的每个节点布置决策逻辑是不能满足要求的,所以我们在制作PCB规则引擎必 ...

  5. PCB 规则引擎之JSON对象查看器

    在PCB规则引擎开发中,JavaScript V8引擎是处理业务逻辑的, 当然业务逻辑需要数据支撑才行,  即需有将数据推进入到V8引擎.目前这边数据传输到JavaScript V8引擎以C# Mod ...

  6. 【java规则引擎】基本语法和相关属性介绍

    一个规则的语法信息 [1]条件部分(LSH部分)===>规则pattern之间的连接条件符号:   (1)LHS 部分是由一个或多个条件组成,条件又称之为 pattern(匹配模式),多个 pa ...

  7. IDEA编写 Scala时没有语法检查和错误提示

    #问题描述 在IDEA中写scala程序时,一些明显的语法错误不进行检查,没有像写Java时的红线什么的,当编译运行时,编译失败. https://blog.csdn.net/weizheng1000 ...

  8. 关于pydev的语法的错误提示

    第三方包引入时,eclipse默认会把一些包定为错误的,错误是:“undefined variable from import...” 其实是对的,可是报错,很烦人 解决方法:window -- pr ...

  9. DELL_LCD错误提示代码

    代码 文本 原因E1000 Failsafe voltage error. Contact support.(故障保护电压错误.请联络支持人员.) 查看系统事件记录以了解严重故障事件.E1114 Am ...

随机推荐

  1. 使用TransactionTemplate

    通过TransactionCallback接口中的方法后(这里用来做业务),将返回值传递到TransactionTemplate的execute()中.通过调用TransactionStatus 的s ...

  2. Gym - 101670H Dark Ride with Monsters(CTU Open Contest 2017 贪心)

    题目: A narrow gauge train drives the visitors through the sequence of chambers in the Dark Ride attra ...

  3. mysql insert一条记录后 返回创建记录主键id的方法

    mysql插入数据后返回自增ID的方法 mysql和oracle插入的时候有一个很大的区别是,oracle支持序列做id,mysql本身有一个列可以做自增长字段,mysql在插入一条数据后,如何能获得 ...

  4. oop设计模式抽象总结

    创建型模式: 一.简单工厂,工厂方法,抽象工厂 简单工厂:只有一层抽象,由工厂去获得抽象类的具体对象,工厂内的方法可以看做静态方法 工厂方法:有两个抽象,工厂的抽象和具体类的抽象. 举个例子: 有个汽 ...

  5. 原生js实现三个按钮绑定三个计时器,点击其中一个按钮,开启当前计时器,另外另个不开启

    今天在某个前端交流群,有个小伙伴问了一个小功能,自己想了一下,代码如下,可以实现基本功能: 下面是html结构 <div id="demo"> <input ty ...

  6. Python基础之生成器、迭代器

    一.字符串格式化进阶 Python的字符串格式化有两种方式: 百分号方式.format方式,由于百分号的方式相对来说比较老,在社区里讨论format方式有望取代百分号方式,下面我们分别介绍一下这两种方 ...

  7. 438D - The Child and Sequence

    D. The Child and Sequence time limit per test 4 seconds memory limit per test 256 megabytes input st ...

  8. 最小生成树+BFS J - Borg Maze

    The Borg is an immensely powerful race of enhanced humanoids from the delta quadrant of the galaxy. ...

  9. OSX: node中安装zeromq

    1. brew install pkg-config2. brew install zmq3. export PKG_CONFIG_PATH="/usr/local/lib/pkgconfi ...

  10. socket短连接、长连接

    通常短连接是这样:连接->传输数据->关闭连接那什么是长连接?一般长连接相对短连接而言的,长连接在传输结束后不关闭连接,而不断的发送包保持连接等待处理下一个数据包. 一般长连接用于少数cl ...