Академический Документы
Профессиональный Документы
Культура Документы
. ., . .
, 2006
....................................................................................................................................2
1.
.................................................................4
1.1.
____________________________________ 4
1.2.
. ________ 9
1.3.
______________________________ 10
1.4.
_____________________________________ 14
2.
...................................18
2.1.
____________ 18
2.2.
______________________________________________ 19
2.3.
___________________________________________ 21
2.4.
_________________________________ 23
......................................................................................26
..............................................................................27
......................................................................................28
......................................................28
..............................................................29
2.5.
___________________________________________ 32
2.6.
________________________________________ 33
2.7.
_____________________________ 35
2.8.
3.
..........................................38
3.1.
_______________________ 38
3.2.
XML XML___________________________________________ 41
3.3.
SOAP: ______________________ 44
3.4.
WSDL: ________________ 45
3.5.
________________________ 49
i
4.
4.1.
_______________________________________ 51
4.2.
4.3.
XmlSerializer ___________________________________ 56
4.4.
4.5.
______________________ 71
5.
...........................................................................................................................73
5.1.
MSMQ ________________________________ 73
5.2.
, MSMQ _______________ 75
5.3.
MSMQ ______ 77
5.4.
5.5.
MSMQ __________________________________ 89
6.
6.1.
COM+ _____________________________ 91
6.2.
COM+___________________________________________________ 93
...............................................................................................................93
..................................................................................................94
Just-in-time- ..........................................................................94
..........................................................................................95
..............................................................................................97
..............................................................................................98
............................................................................................99
6.3.
6.4.
7.
7.1.
- ___________________________________________ 125
7.2.
7.3.
- ..................................................................................................130
- ..............................................................................132
7.4.
7.5.
________________________________ 138
7.6.
- _______________________________ 148
8.
8.1.
8.2.
8.3.
8.4.
8.5.
8.6.
___________________________________ 170
8.7.
9.
9.1.
_______________________________ 181
9.2.
______________________________ 183
..........................................................................................183
Kerberos........................................................................................................186
9.3.
9.4.
_______________________ 189
10.
.................................................................190
10.1.
__________________________________ 190
10.2.
______________ 191
10.3.
iii
..................................................................................195
I. COM+ .......................................................196
II. ASP.NET IIS..............................................................199
III. ....................................................................204
iv
, . , , s_gorin@mail.ru.
, ..., . , ,
mstu@sevik.ru.
1. Microsoft .NET Framework 2.0
2. Microsoft Windows XP Pro SP2, Microsoft
Server 2003,
MSMQ, COM+ IIS
Microsoft Microsoft Windows
Microsoft Corporation, .
.
, .
,
.
, ,
C/++.
, Microsoft,
(Common Language Infrastructure, CLI),
.NET,
. Microsoft .NET
Framework ,
:
(messaging queues), COM+, .NET Remoting, - (web services).
,
.
,
.
.
1. ,
.
2. ,
Microsoft .NET, .
3.
, .
2
.
Microsoft.NET Framework,
C#, TCP/IP,
, .
( 2006 )
.NET .
.
1.
1.
,
. .
.
1.1.
. ,
. ,
, ,
,
. , ,
,
(single point of failure).
.
,
. . ,
,
.
.
,
,
. , ,
.
1.
-, ()
, ().
(. 1.1).
1.1. -
- ,
, ,
.
.
, .
1.2.
,
(. 1.2):
5
1.
(), () (),
().
, ,
, ,
.
,
, ,
,
. ,
, (. 1.3).
1.3.
- .
.
- ,
,
6
1.
,
(. 1.4).
1.4.
, .
,
.
1.5.
1.
,
,
. ,
,
, ,
( 1.5).
,
,
.
(peer-to-peer networks).
,
, . 1.6.
,
1.6.
1.
1.2.
. , ,
, ,
.
, , .
.
,
,
, ,
, .
.
1.7.
9
1.
CLI,
(application domain),
.
,
. ,
,
(. 1.7).
.
, .
.
.
.
. ,
, -
.
1.3.
. ,
.
10
1.
.
.
.
.
.
,
.
.
.
, (load balancing)
.
, .
,
. ,
, , .
.
.
,
.
. , ,
,
. , ,
, .
11
1.
.
,
.
, ,
,
. ,
,
.
,
.
TCP/IP.
(unix sockets) POSIX-
(named pipes).
,
. ,
,
. ,
. ,
,
,
.
, : ,
, ,
,
.
.
,
12
1.
IP- (DNS).
,
(. 1.8).
DNS-
1.8. DNS
(, w3c.org)
.
.
, ,
. , (
.org), , ,
.
.
.
,
. , -
13
1.
.
, , .
1.4.
,
.
OSI/ISO,
: , , , ,
, , .
1
1.9.
TCP/IP TCP
, IP .
,
14
1.
.
.
TCP/IP ,
SSL/TLS.
TCP/IP ,
,
.
(middleware),
(. 1.9).
,
.
. :
: ,
;
(. 1.10).
,
,
.
15
1.
1.10.
,
, , ,
.
,
, .
,
, .
,
:
, , ,
, .
,
, .
16
1.
,
, .
, , ,
.
17
3.
2.
.
.
.
2.1.
.
:
.
TCP/IP,
,
. TCP HTTP
.
,
,
.
- ,
TCP/IP,
. ,
, ,
, , ,
. ,
, ,
18
3.
.
2.2.
.
, ,
.
.
,
.
.
, -
.
,
.
,
.
,
. , , Microsoft Message
Queuing, IBM MQSeries Sun Java System Message Queue.
,
;
;
19
3.
, .
,
.
, .
,
, ,
(. 2.1).
2.1.
.
:
,
.
;
20
3.
:
, .
2.3.
2.2.
21
3.
.
1. :
;
2. : ,
,
(, , ).
: ,
,
callback-,
.
(
.NET)
(marshaling). -
. ,
.
(marshal by value),
.
,
.
.
,
.
,
.
22
3.
2.4.
(remote
method invocation, RMI). ,
.
. ,
,
. ,
,
.
.
, ,
, (proxy).
, .
, ,
.
, (skeleton) ,
, (. 2.3).
. ,
,
, .
(marshal by reference). ,
,
.
,
.
23
3.
Cc
2.3.
,
, .
, . -,
(exceptions) ,
,
, .
-,
( 2.4),
RMI.
24
3.
2.4. ,
:
:
,
: .
(singlecall), (singleton),
(client activation).
(server activation), , ,
- .
25
3.
.
,
. ,
.
,
.
(. 2.5).
2.5.
,
. ,
.
, ,
,
26
3.
, .
, , (object
pooling).
, ,
.
. ,
,
.
,
.
. ,
(. 2.6).
2.6.
.
27
3.
.
,
- .
,
.
(, )
, ,
.
,
,
(. 2.7).
2.7. , .
:
(stateless components);
28
3.
,
(statefull components).
, .
- ,
,
.
,
,
,
.
,
.
,
.
,
.
processing.FirstName = "";
processing.SecondName = "";
processing.ThirdName = "";
processing.City = "";
result = processing.Run();
29
3.
processing , Run()
. , processing
. , , .
1. ,
(set C#).
Run (
) ( ).
2. ,
. ,
,
. .
3. ,
,
(
).
,
,
4. .
,
.
,
,
.
,
.
.
.
30
3.
( chunky design)
, .
result = processing.Run("", "", "", "");
, ,
. : ,
, , .
,
,
.
person.FirstName = "";
person.SecondName = "";
person.ThirdName = "";
person.City = "";
result = processing.Run(person);
.
,
.
.
task.Epsilon = 1e-5:
task.X1 = -1;
task.X2 = 1;
task.MaximumSteps = 20;
task.Function += X2Function;
result = processing.Run(processingArguments);
...
double X2Function(double x)
{
return x*x;
}
processing , , ,
X2Function.
-,
, -, ,
.
31
3.
(, , )
.
,
, .NET Framework
.
C#.
2.5.
- , ,
.
,
.
.
. , ,
, ,
:
,
()
().
, -
, ( 2.8).
32
3.
2.8.
,
.
.
2.6.
- ,
(
). .
. .
.
,
.
. ,
.
,
, .
.
(.. ).
33
3.
2.9.
, ,
. ,
,
(. 2.9).
.
- , ,
, .
. :
-
, .
.
,
( )
,
.
34
3.
(compensating resource manager).
.
,
(business
activity) .
, , :
.
( , ,
). ,
,
(, ).
(,
) .
2.7.
,
.
1.
(1). ,
, ,
.
2.
().
,
(role-based security).
authentication identification.
35
3.
,
,
.
3. , ,
.
, .
,
, , .
2.8.
,
, 90- ,
,
. CLR
. .NET Framework
.
.NET Framework Class Library
.
.
3.
.NET Remoting
.
37
3.
3.
,
, .
.
3.1.
.
,
. ,
, .NET Framework,
:
,
;
-,
.
.
.
,
. HTTP, TCP, NetBIOS,
.
.
,
-.
,
38
3.
, , ,
.
- ,
,
(
-).
,
, .
-
,
-.
. ,
(
).
. ,
, ,
- . ,
CLI.
.
,
,
.
, ,
39
3.
.
.
, .
, :
();
().
(. 3.1).
3.1.
:
, .
.
,
.
.NET.
40
3.
,
, .NET Framework.
, ,
,
.
.
3.2.
XML XML
XSD:
WSDL:
SOAP:
3.2. XML
XML ,
, .
,
41
3.
().
XML
- . XML
.
. ,
, ,
,
.
<?xml version="1.0" encoding="utf-8"?>
<GeomFigures>
<Point X="2" Y="-1" />
<Line>
<A X="-1" Y="-1" />
<B X="2" Y="2" />
</Line>
</GeomFigures>
XML
, ,
,
XML .
XML
, XML-DigitalSignature
XML-Encrypton,
XML
. XML- ,
XML- .
XML-
XML (XML namespace),
. URI
(Uniform Resource Identifier), ,
. URI
, . XML-
xmlns:schema_id.
42
3.
schema_id,
.
http://www.w3.org/2001/XMLSchema xs,
xs:schema.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
,
.
.
XML .
XML ,
XML-. DTD (Document
Type Definition),
XML (XML Schema Definition, XSD). XSD-
XML,
http://www.w3.org/2001/XMLSchema. XML :
( );
http://www.w3.org/2001/XMLSchema.
, , ,
,
. ,
XML ( ),
. .NET
Framework xsd.exe, ,
. .NET
. ,
xsd.exe
XML.
43
3.
3.3.
SOAP:
XML
,
, . 90-
SOAP XML-RPC. XML-RPC
,
.NET Framework.
HTTP
,
,
. , SOAP
- , SOAP
WSDL - (web services).
SOAP
3.
SOAP SOAP-RPC ( ) SOAP-Document.
SOAP-RPC
.
SOAP-Document,
, XML-
, WSDL.
, -
.
SOAP 1.2 ,
http://summa.test/webservices, ,
. message .
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<Add xmlns="http://summa.test/webservices">
<message>
<a>1</a>
<b>2</b>
</message>
</Add>
</soap12:Body>
</soap12:Envelope>
.
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<AddResponse xmlns="http://summa.test/webservices">
<AddResult>3</AddResult>
</AddResponse>
</soap12:Body>
</soap12:Envelope>
3.4.
WSDL:
,
, WSDL (Web Service Definition Language).
WSDL (. 3.3).
45
3.
3.3. WSDL-
1.
SOAP-Document XML, ,
SOAP.
2. ,
.
3. ( ),
.
4. ( ),
.
5. (binding),
, SOAP.
6. ,
URL.
7. ( )
.
WSDL ,
.
46
3.
wsdl:types . Add
, AddResponse
.
<wsdl:types>
<s:schema elementFormDefault="qualified"
targetNamespace="http://summa.test/webservices">
<s:element name="Add">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="message"
type="tns:AddMessage" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="AddMessage">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="a" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="b" type="s:int" />
</s:sequence>
</s:complexType>
<s:element name="AddResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="AddResult" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
SumList SumListResponse
.
<s:element name="SumList">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="list"
type="tns:ArrayOfInt" />
</s:sequence>
</s:complexType>
</s:element>
47
3.
<s:complexType name="ArrayOfInt">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="int" type="s:int" />
</s:sequence>
</s:complexType>
<s:element name="SumListResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="SumListResult"
type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
wsdl:message .
<wsdl:message name="AddSoapIn">
<wsdl:part name="parameters" element="tns:Add" />
</wsdl:message>
<wsdl:message name="AddSoapOut">
<wsdl:part name="parameters" element="tns:AddResponse" />
</wsdl:message>
<wsdl:message name="SumListSoapIn">
<wsdl:part name="parameters" element="tns:SumList" />
</wsdl:message>
<wsdl:message name="SumListSoapOut">
<wsdl:part name="parameters" element="tns:SumListResponse" />
</wsdl:message>
wsdl:portType
.
<wsdl:portType name="MathServiceSoap">
<wsdl:operation name="Add">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
Add
</wsdl:documentation>
<wsdl:input message="tns:AddSoapIn" />
<wsdl:output message="tns:AddSoapOut" />
</wsdl:operation>
<wsdl:operation name="SumList">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
SumList
</wsdl:documentation>
<wsdl:input message="tns:SumListSoapIn" />
<wsdl:output message="tns:SumListSoapOut" />
</wsdl:operation>
</wsdl:portType>
wsdl:binding (HTTP),
SOAP (1.2) (SOAP-Document).
48
3.
<wsdl:binding name="MathServiceSoap12" type="tns:MathServiceSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Add">
<soap12:operation soapAction="http://summa.test/webservices/Add"
style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SumList">
<soap12:operation soapAction="http://summa.test/webservices/SumList"
style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
wsdl:service
, , URL,
-.
<wsdl:service name="MathService">
<wsdl:port name="MathServiceSoap12" binding="tns:MathServiceSoap12">
<soap12:address location="http://summa.test/webservices/summa.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
, WSDL
,
,
, SOAP.
WSDL- ,
WSDL- .
3.5.
.
49
3.
: XML, XSD, SOAP WSDL.
, -
.
SOAP
,
, SOAP.
WSDL
SOAP .
50
4. . .NET Framework
4. .
.NET Framework
. ,
.
, .NET Framework, .
4.1.
, .NET Framework
,
,
.
CLR.
.
,
(,
, ) -,
,
( 4.1). ,
, .
1
4.1.
51
4. . .NET Framework
- ( System.ValueType) ,
.
.
, , ,
, (object graph).
-,
.
G = < V, E > ,
( V), , ,
( 4.2).
public class SampleClass
{
public SampleClass fieldA = null;
public SampleClass fieldB = null;
}
...
SampleClass root = new SampleClass();
SampleClass child1 = new SampleClass();
SampleClass child2 = new SampleClass();
root.fieldA = child1;
root.fieldB = child2;
child1.fieldA = child2;
...
root
child 1
child 2
4.2.
B A < A, B >
E.
- ,
. ,
CLI .
52
4. . .NET Framework
,
.
, .
.
, , ,
, , .
,
-
.
, < A, B1>, ... < A, Bn >, S
A S(A) = < V(A), <S(B1), ... S(Bn)>>, V
- .
,
( < A1, B>
< A2, B >). A ... A.
, ,
,
. A1, ... An ,
{< idA1, S(A1) >, ... <idAn, S(An) >},
S(A) S(A) = < V(A), <idB1, ... idBn> >, B1, ... Bn ,
A.
,
.
, ,
.
53
4. . .NET Framework
, XML,
.
, ,
, .
, -
.
4.2.
.NET Framework
- ASP.NET XmlSerializer;
MSMQ
XmlSerializer
Enterprise
Services
Remoting
BinaryFormatter.
54
4. . .NET Framework
.
1. :
: ;
2. :
, ,
;
, XML ,
.
3. ,
:
:
, ;
,
;
:
, XSD.
XmlSerializer
, BinaryFormatter ,
SoapFormatter .
, BinaryFormatter, ,
. .
55
4. . .NET Framework
4.3.
XmlSerializer
System.Xml.Serialization.XmlSerializer
, XML
XML .
, , - ASP.NET
MSMQ. XmlSerializer
XML, .
XmlSerializer XML
.
, XmlSerializer ,
,
.
XML ,
, . ,
(generic) XML-
.
. , IVehicle vehicleValue
, IVehicle.
CLI
System.XML.Serialization.XmlAttrbute,
- ,
XML-.
XmlAttrbuteAttrbute.
[System.XML.Serialization.XmlAttrbute(typeof(Car)),
System.XML.Serialization.XmlAttrbute(typeof(Bike)),
System.XML.Serialization.XmlAttrbute(typeof(LongTruck))]
IVehicle vehicleValue;
, ,
CLI XML,
.
56
4. . .NET Framework
XmlSerializer .
-, :
. -, ,
.
,
( 4.3). XML-
- , , ,
, ,
- .
root
child 1
root
child 2
child 2
child 1
child 2
4.3. XmlSerializer
XmlSerializer
IEnumerator.Current
GetEnumerator .
57
4. . .NET Framework
IEnumerator, GetEnumerator,
.
3.
System.Collections.ICollection,
IEnumerable. Item
, ICollection.
.
4. ICollection IEnumerable,
Item c Count.
, Add, Item
. .
5. IXMLSerializer, IEnumerable, ICollection
System.SerializableAttribute.
,
.
, get set. ,
,
, .
//
public int[,] data = new int[2,2];
58
4. . .NET Framework
, FCL, IDictionary,
( Add ).
XmlSerializer ,
System.Collections.IDictionary,
System.Collections.Hashtable. ,
Hashtable IXmlSerializable. XMLSerializer
FCL:
System.XML.XmlNode
System.XML.XmlDocumnt
System.XML.XmlElement, XML-
XML- ( ,
);
System.Data.Dataset;
,
System.Xml.Serialization ,
XML, .
NonSerializedAttribute ,
.
,
IXMLSerializable -
.
, .
59
4. . .NET Framework
using System.Xml;
using System.Collections;
using System.Xml.Serialization;
public class DictionaryCollection<TValue> : DictionaryBase, IXmlSerializable
{
private XmlSerializer valueSerializer;
private XmlSerializer keySerializer;
public DictionaryCollection()
{
keySerializer = new XmlSerializer(typeof(String));
valueSerializer = new XmlSerializer(typeof(TValue));
}
,
, .
public TValue this[string key]
{
get { return (TValue)this.Dictionary[key]; }
set { this.Dictionary[key] = value; }
}
public void Add(String key, TValue value)
{
this.Dictionary.Add(key, value);
}
XMLSerializer WriteXml
ReadXML.
public void WriteXml(System.Xml.XmlWriter writer)
{
foreach (String key in this.Dictionary.Keys)
{
keySerializer.Serialize(writer, key);
valueSerializer.Serialize(writer, this[key]);
}
}
public void ReadXml(System.Xml.XmlReader reader)
{
reader.Read();
while (reader.NodeType != XmlNodeType.EndElement)
{
String key = (String) keySerializer.Deserialize(reader);
TValue value = (TValue) valueSerializer.Deserialize(reader);
reader.MoveToContent();
Add(key, value);
}
}
60
4. . .NET Framework
GetSchema XSD- .
, .
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
} // DictionaryCollection<TValue>
,
- .
DictionaryCollection<Int32> dictionary = new DictionaryCollection<Int32>();
XmlSerializer serializer = new XmlSerializer(typeof(DictionaryCollection<Int32>));
dictionary.Add("key1", 10);
dictionary.Add("key2", 20);
using (StreamWriter writer = new StreamWriter("sample.xml"))
{
XmlTextWriter xmlWriter = new XmlTextWriter(writer);
xmlWriter.Formatting = Formatting.Indented;
serializer.Serialize(xmlWriter, dictionary);
}
IXmlSerializable,
System.Xml.Serialization, XML-. , ,
XmlAttributeAttribute,
XmlArrayItemAttribute,
XmlElementAttribute,
XmlIgnoreAttribute.
XmlArrayAttribute,
, .
XmlAttributeAttribute XmlElementAttribute
. XML
, . XmlElementAttribute
. ,
, , XML-
xsi:type .
XmlArrayAttribute, XmlArrayItemAttribute
. , (, ArrayList)
(, List<T>). XmlArray
61
4. . .NET Framework
XmlAttribute , XmlArrayItem
XML. XmlArrayItem
, .
, ,
. , List<Person> persons
Person, XmlArrayItem .
.
// figures.cs
using System;
using System.IO;
using System.Xml.Serialization;
using System.Collections.Generic;
public abstract class GeomFigure
{
}
,
. .
62
4. . .NET Framework
public class GeomPoint: GeomFigure
{
private double xField, yField;
[XmlAttribute("X")]
public double X
{
get {return xField;}
set {xField = value;}
}
[XmlAttribute("Y")]
public double Y
{
get {return yField;}
set {yField = value;}
}
public GeomPoint()
{
}
public GeomPoint(double x, double y)
{
this.X = x;
this.Y = y;
}
public override string ToString()
{
return String.Format("({0}, {1})", X, Y);
}
}
public class GeomLine: GeomFigure
{
private GeomPoint aField, bField;
public GeomPoint A
{
get {return aField;}
set {aField = value;}
}
public GeomPoint B
{
get {return bField;}
set {bField = value;}
}
public GeomLine()
{
}
public GeomLine(GeomPoint a, GeomPoint b)
{
this.A = a;
this.B = b;
}
63
4. . .NET Framework
public override string ToString()
{
return String.Format("{0} {1}", A, B);
}
}
XmlArrayItem
.
public class GeomFigures
{
private List<GeomFigure> figuresField;
[XmlArrayItem("Point", typeof(GeomPoint)),
XmlArrayItem("Line", typeof(GeomLine))]
public List<GeomFigure> Figures
{
get { return figuresField;}
}
public GeomFigures()
{
figuresField = new List<GeomFigure>();
}
}
public class App
{
public static void Main()
{
GeomFigures figures = new GeomFigures();
figures.Figures.Add(new GeomPoint(2, -1));
figures.Figures.Add(new GeomLine(new GeomPoint(-1, -1),
new GeomPoint(2, 2)));
XmlSerializer serializer = new XmlSerializer(typeof(GeomFigures));
using (StreamWriter writer = new StreamWriter("figures.xml"))
{
serializer.Serialize(writer, figures);
};
}
}
XML-.
<?xml version="1.0" encoding="utf-8"?>
<GeomFigures xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Figures>
<Point X="2" Y="-1" />
<Line>
<A X="-1" Y="-1" />
<B X="2" Y="2" />
</Line>
</Figures>
</GeomFigures>
64
4. . .NET Framework
,
XSD- .
.NET Framework xsd.exe, :
(partial) # XSD;
XSD #;
XSD XML- (
).
,
schema0.xsd XML.
xsd.exe figures.exe /type:GeomFigures
.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="GeomFigures" nillable="true" type="GeomFigures" />
<xs:complexType name="GeomFigures">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="Figures" type="ArrayOfChoice1" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="ArrayOfChoice1">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element minOccurs="1" maxOccurs="1" name="Point" nillable="true"
type="GeomPoint" />
<xs:element minOccurs="1" maxOccurs="1" name="Line" nillable="true"
type="GeomLine" />
</xs:choice>
</xs:complexType>
<xs:complexType name="GeomPoint">
<xs:complexContent mixed="false">
<xs:extension base="GeomFigure">
<xs:attribute name="X" type="xs:double" use="required" />
<xs:attribute name="Y" type="xs:double" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="GeomFigure" abstract="true" />
<xs:complexType name="GeomLine">
<xs:complexContent mixed="false">
<xs:extension base="GeomFigure">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="A" type="GeomPoint" />
<xs:element minOccurs="0" maxOccurs="1" name="B" type="GeomPoint" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
65
4. . .NET Framework
XML- C#,
XML- .
xsd.exe schema0.xsd /classes
,
XmlSerializer
, C#
XSD-. 4.4
XML- .
XMLSerializer XML
, ,
WSDL.
1
XML
4.4. XML
XMLSerializer ,
. ,
GeomFigures.XmlSerializers,
.
(,
,
66
4. . .NET Framework
), sgen.exe
.
XMLSerializer, ,
,
XSD. XMLSerializer
XmlDocument
Dataset,
XML- .
,
XML- . XmlSerializer
,
.
4.4.
SoapFormatter BinaryFormatter
System.Runtime.Serialization.Formatters.Soap.SoapFormatter
.NET
Remoting,
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
MSMQ XMLSerializer.
.
BinaryFormatter
SoapFormatter ,
SOAP-RPC ( http://schemas.xmlsoap.org/soap/encoding/).
.NET Framework 2.0
SoapFormatter
SoapFormatter
(generic types).
( ), . ,
System.NonSerializeAttribute,
67
4. . .NET Framework
System.SerializableAttribute.
System.Runtime.Serialization.FormatterServices.
,
.
ISerializable,
GetObjectData(SerializationInfo info, StreamingContext context)
, FormatterServices.
System.Runtime.Serialization.IDeserializationCallback
OnDeserialization.
SerializationInf .
, IFormatter,
, .
ISerializable
.
using
using
using
using
using
using
System;
System.IO;
System.Runtime.Serialization;
System.Runtime.Serialization.Formatters;
System.Runtime.Serialization.Formatters.Binary;
System.Reflection;
[Serializable]
public class Person : ISerializable
{
public String name;
public Person()
{
}
68
4. . .NET Framework
GetObjectData .
SerializationInfo ,
.
GetSerializableMembers FormatterServices.
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
Type thisType = this.GetType();
MemberInfo[] serializableMembers =
FormatterServices.GetSerializableMembers(thisType, context);
foreach (MemberInfo serializableMember in serializableMembers)
{
// NonSerializedAttribute
if (!(Attribute.IsDefined(serializableMember,
typeof(NonSerializedAttribute))))
{
info.AddValue(serializableMember.Name,
((FieldInfo)serializableMember).GetValue(this));
}
}
}
SerializationInfo.
protected Person(SerializationInfo info,
StreamingContext context)
{
Type thisType = this.GetType();
MemberInfo[] serializableMembers =
FormatterServices.GetSerializableMembers(thisType, context);
foreach (MemberInfo serializableMember in serializableMembers)
{
FieldInfo fieldInformation = (FieldInfo)serializableMember;
if (!(Attribute.IsDefined(serializableMember,
typeof(NonSerializedAttribute))))
{
fieldInformation.SetValue(this,
info.GetValue(fieldInformation.Name,
fieldInformation.FieldType));
}
}
}
} // Person
Person.
public class SampleApp
{
public static void Main()
{
using (Stream stream = new MemoryStream())
{
IFormatter formatter = new BinaryFormatter();
69
4. . .NET Framework
Person person = new Person();
person.name = "";
Console.WriteLine(": {0}", person.name);
formatter.Serialize(stream, person);
stream.Position = 0;
Person personRestored = (Person) formatter.Deserialize(stream);
Console.WriteLine(": {0}", personRestored.name);
}
}
}
,
.
,
.
,
, ,
.
SurrogateSelector ,
System.Runtime.Serialization.ISurrogateSelector.
. .NET Remoting ,
MarshalByRefObject .
BinaryFormatter MSMQ MarshalByRefObject
,
BinarryMessageFormatter MarshalByRefObject
SurrogateSelector.
BinaryFormatter
, .
,
.
CLI,
.
,
CLI.
70
4. . .NET Framework
XML.
System.Xml.XmlDocument
BinaryFormatter SoapFormatter,
Serializable.
XmlDocument , .
XmlDocument,
ISerializable.
,
XmlDocument .
XmlDocument.ToString() XML-
, LoadXml, StringWriter.
// SevaXmlUtils.cs
using System;
using System.IO;
using System.Xml;
namespace Seva.Xml
{
public static class XmlUtils
{
public static String XmlToString(XmlDocument xml)
{
StringWriter xmlLine = new StringWriter();
xml.Save(xmlLine);
return xmlLine.ToString();
}
public static XmlDocument XmlFromString(String xmlLine)
{
XmlDocument xml = new XmlDocument();
xml.LoadXml(xmlLine);
return xml;
}
}
}
4.5.
.NET Framework
,
.
(
-, - ),
. , ,
71
4. . .NET Framework
( System.Data.Dataset) XML ( System.Xml.XMLDocument).
,
.
72
5. MSMQ
MSMQ
.
,
MSMQ, Sun Java System Message Queue, IBM MQSeries, Oracle Advanced Queing.
MSMQ Microsoft
,
Windows NT. MSMQ 3.0,
Windows XP PE 2003 Server, 2.0,
Windows 2000.
MSMQ
, .
, MSMQ, :
, .
, ,
(2 MSMQ 2.0).
MSMQ
2.0/3.0
.NET Framework.
73
5. MSMQ
MSMQ
, .
. MSMQ ,
. :
(
);
,
;
MSMQ ,
( MSMQ 3.0).
MSMQ
MSMQ
MSMQ
MSMQ
5.1. MSMQ
, MSMQ
( UDP)
, 5 .
, 5
74
5. MSMQ
,
MSMQ. ,
.
MSMQ
( 5.1).
, MSMQ ,
.
MSMQ
IBM IBM Websphere MQ ( MQSeries).
Websphere MQ .NET Framework,
, MSMQ,
MSMQ
Windows. MSMQ-MQSeries
,
IBM MQ .
.
Microsoft Message Queuing,
Microsoft Active Directory.
5.2.
, MSMQ
75
5. MSMQ
MSMQ (public) (private).
, ,
,
.
Active Directory.
ComputerName\QueueName,
.\QueueName .
.
HTTP-
.
MSMQ (direct name)
(path name).
. MSMQ
.NET Framework :
Formatname:DIRECT=OS:server01\QueueName
server01;
76
5. MSMQ
Formatname:DIRECT=OS:ws02\Private$\QueueName
ws01;
Formatname:DIRECT=TCP:192.168.30.1\private$\QueueName
192.168.30.1.
, Windows RPC
( , 135- ). , MSMQ
NAT, HTTP-
.
5.3.
MSMQ
, MSMQ
.
1. . :
XML- XSD-,
. MSMQ .
2. . MSMQ Windows NT
(ACL) , AD
. , , MSMQ,
Active Directory.
3. . MSMQ ,
, .
,
77
5. MSMQ
4. . MSMQ ,
COM+ System.Transactions.
,
(, )
, .
COM+
System.Transactions
(MS DTC).
, ,
, .
, MSMQ
,
, MSMQ
. COM+
.
5. .
MSMQ
. ,
.
.
,
MSMQ .
.
1. ,
.
2. MSMQ LAN/VPN. -
HTTP
, VPN,
.
78
5. MSMQ
3. - MSMQ
.
, ,
,
.
.
(.\Private$\LocalQueueName)
(SomeComputer\Private$\RemoteQueueName).
MSMQ, ,
.
,
.
,
- ,
( ).
( -), , ,
.
,
.
,
. MSMQ
,
. MSMQ
:
( );
.
79
5. MSMQ
,
,
. , MSMQ
,
- , MSMQ
.NET Framework
,
.
,
,
( ).
MSMQ
, .
- ,
. , MSMQ
.NET Framework , ,
.
,
ICMP,
MSMQ .
,
.
5.4.
System.Messaging. System.Messaging.MessageQueue
.
1. : Create, Delete, Exists, Purge.
80
5. MSMQ
2. : GetPublicQueues, GetPublicQueuesByLabel
. ,
Active Directory,
.
3. (Send, Receive, Peek ),
(BeginPeek,
BeginReceive).
System.Messaging
:
, ;
, ,
MSMQ;
, ,
COM+.
BinaryMessageFormatter
XMLMessageFormatter
System.Xml.Serialization.XmlSerializer, ,
XMLMessageFormatter
XmlSerializer. BinaryMessageFormatter
BinaryFormatter.
81
5. MSMQ
BinaryFormatter XmlSerializer
,
BinaryMessageFormatter XMLMessageFormatter
.
XMLMessageFormatter.
MSMQ
XSD-
. MSMQ
, BinaryMessageFormatter,
.
,
-
MSMQ ( 5.2).
MSMQ
5.2. MSMQ
System.Messaging .
using System;
using System.Messaging;
using System.Collections.Generic;
,
.
namespace Seva.Msmq
{
//
enum QueueType {NonTransactional, Transactional};
//
enum QueueFormatter {Binary, Xml};
82
5. MSMQ
//
delegate AnswerType ProcessRequestEventHandler
<RequestType, AnswerType>(Object sender, RequestType request,
MessageQueue queueResponse);
//
delegate void ProcessAnswerEventHandler<RequestType, AnswerType>
(Object sender, RequestType request, AnswerType answer);
, MSMQ .
class MsmqClient<RequestType, AnswerType> :
MsmqUser<RequestType, AnswerType>, IDisposable
{
//
private MessageQueue queueSend;
private MessageQueue queueReceive;
//
private Dictionary<String, RequestType> messages;
public Dictionary<String, RequestType> Messages
{
get { return messages;}
}
83
5. MSMQ
// ,
public event ProcessAnswerEventHandler<RequestType, AnswerType>
ProcessAnswer;
, .
public MsmqClient(String queueSendName, String queueReceiveName,
QueueFormatter formatterType): base(formatterType)
{
//
messages = new Dictionary<String,RequestType>();
// ,
queueSend = MsmqTools.CreateQueue(queueSendName,
QueueType.Transactional);
// ,
if (queueReceiveName != null)
{
queueReceive = MsmqTools.CreateQueue(queueReceiveName);
queueReceive.Formatter = answerFormatter;
// CorrelationId
queueReceive.MessageReadPropertyFilter.CorrelationId = true;
}
else
{
queueReceive = null;
}
}
Dispose .
public void Dispose()
{
queueSend.Close();
queueSend.Dispose();
if (queueReceive != null)
{
queueReceive.Close();
queueReceive.Dispose();
}
}
BeginReceive EndReceive ,
PeekComplete .
public void BeginReceive()
{
// ,
//
queueReceive.PeekCompleted += OnPeek;
//
queueReceive.BeginPeek();
}
84
5. MSMQ
//
public void EndReceive()
{
//
queueReceive.PeekCompleted -= OnPeek;
}
Send
. ,
ResponseQueue .
public void Send(RequestType request)
{
//
Message message = new Message(request, requestFormatter);
message.ResponseQueue = queueReceive;
//
message.Recoverable = Recoverable;
// ;
// , -
// MessageQueueTransactionType.Single
queueSend.Send(message, MessageQueueTransactionType.Single);
// message.Id ;
// c
//
messages.Add(message.Id, request);
}
PeekComplete MSMQ.
ProcessAnswer. ,
.
.
public void OnPeek(Object source, PeekCompletedEventArgs asyncResult)
{
// MSMQ
MessageQueueTransaction transaction = new MessageQueueTransaction();
//
transaction.Begin();
try
{
//
queueReceive.EndPeek(asyncResult.AsyncResult);
//
Message message = queueReceive.Receive(transaction);
85
5. MSMQ
// CorrelationId
//
String messageId = message.CorrelationId;
// ?
if (messages.ContainsKey(messageId))
{
if (message.Body is AnswerType)
{
//
//
AnswerType answer = (AnswerType) message.Body;
ProcessAnswer(this, messages[messageId], answer);
};
messages.Remove(messageId);
}
//
BeginReceive();
//
transaction.Commit();
}
catch (Exception e)
{
//
transaction.Abort();
throw e;
}
}
}
MSMQServer , MSMQ
.
class MsmqServer<RequestType, AnswerType>:
MsmqUser<RequestType, AnswerType>, IDisposable
{
//
private MessageQueue queueReceive;
// ,
public event ProcessRequestEventHandler<RequestType, AnswerType>
ProcessMessage;
.
public MsmqServer(String queueReceiveName, QueueFormatter formatterType):
base(formatterType)
{
// ,
queueReceive = MsmqTools.CreateQueue(queueReceiveName,
QueueType.Transactional);
queueReceive.Formatter = requestFormatter;
}
Dispose .
86
5. MSMQ
public void Dispose()
{
queueReceive.Close();
queueReceive.Dispose();
}
BeginReceive EndReceive ,
PeekComplete .
//
public void BeginReceive()
{
queueReceive.PeekCompleted += OnPeek;
queueReceive.BeginPeek();
}
//
public void EndReceive()
{
queueReceive.PeekCompleted -= OnPeek;
}
OnPeek PeekCompleted .
.
ProcessMessage. ResponseQueue
, .
// PeekCompleted
public void OnPeek(Object source, PeekCompletedEventArgs asyncResult)
{
// MSMQ
MessageQueueTransaction transaction = new MessageQueueTransaction();
//
transaction.Begin();
try
{
queueReceive.EndPeek(asyncResult.AsyncResult);
// c
Message message = queueReceive.Receive(transaction);
// ResponseQueue ,
//
MessageQueue queueResponse = message.ResponseQueue;
try
{
if (message.Body is RequestType)
{
RequestType request = (RequestType) message.Body;
//
AnswerType answer = ProcessMessage(this, request,
queueResponse);
87
5. MSMQ
if ((queueResponse != null) && (answer != null))
{
Message answerMessage = new Message(answer,
answerFormatter);
answerMessage.Label = "Answer";
answerMessage.CorrelationId = message.Id;
answerMessage.Recoverable = Recoverable;
//
queueResponse.Send(answerMessage, transaction);
}
}
}
finally
{
if (queueResponse != null)
{
queueResponse.Close();
queueResponse.Dispose();
}
};
//
BeginReceive();
//
transaction.Commit();
}
catch (Exception e)
{
//
Console.WriteLine(e);
transaction.Abort();
throw e;
}
}
}
MsmqTools
.
static class MsmqTools
{
static public MessageQueue CreateQueue(String queueName)
{
return CreateQueue(queueName, QueueType.Transactional);
}
//
static public MessageQueue CreateQueue(String queueName,
QueueType type)
{
MessageQueue messageQueue;
88
5. MSMQ
// ,
//
try
{
if (!MessageQueue.Exists(queueName))
{
MessageQueue.Create(queueName,
type == QueueType.Transactional);
}
}
catch(Exception)
{
}
MessageQueue messageQueue = new MessageQueue(queueName);
return messageQueue;
}
}
,
, .
queueName = @"Server\PublicQueue";
.
queueName = @"Formatname:DIRECT=OS:Computer\Private$\PrivateName";
.
5.5.
MSMQ
5. MSMQ
MSMQ
(queued components) COM+, ,
COM+. MSMQ
,
COM+ . ,
MSMQ .NET Remoting,
, .
, MSMQ ,
.
90
6. COM+
6. COM+
Enterprise Services
6.1.
COM+
COM+ ,
. Microsoft 90-
Microsoft Windows 2000.
COM+
.
COM+:
,
;
(distributed
transactions coordinator, DTC);
(roles),
COM+
COM+,
COM+. COM+,
, COM+.
COM+ .
COM+.
COM+ : .
,
, ,
.
COM+
COM+.
COM+
91
6. COM+
. (proxy) COM+
COM+,
COM+ , ,
.
COM+
,
,
COM+.
. 6.1 COM+
.
COM+
COM+,
.
COM+ (interceptor).
COM+
COM+
COM+
COM+
RPC
COM+
RPC
COM+
COM+
2
6.1. COM+
COM+
COM+,
92
6. COM+
.
, . , COM+
COM+
. COM+
comexp.msc , comadmin.dll.
I.
COM+
, COM+,
COM+.
.
COM+, .
6.2.
COM+
COM+
COM+ ,
. Windows 2003/XP SP2,
COM+,
.
COM+
.
COM+ .
COM+,
COM+,
, . COM+ ,
COM+
. ,
. COM+
( ), ,
93
6. COM+
COM+ ,
6.1.
6.1 COM+
COM+
(Not Supported)
(Supported)
(Required)
(Requires new)
,
, .
COM+ .
COM+ Microsoft
Windows (Windows 2000 Advanced Server ). COM+
COM+.
Windows Clustering
Services. , COM+
.
Just-in-time-
COM+
( COM+
JIT-)
94
6. COM+
,
.
COM+
.
COM+ .
, Not supported,
JIT-
Required Requires new. COM+
6.2
6.2 COM+
COM+
(Not Supported)
(Supported)
(Required)
(Requires new)
,
COM+
(. 6.2).
, ,
COM+.
, , MSMQ MS SQL.
.
95
6. COM+
COM+
ID
ID
COM+
6.2. COM+
. ,
, COM+
(. 6.3).
6.3. COM+
96
6. COM+
MSMQ COM+,
MSMQ
COM+, .
COM+
(queued componenets),
MSMQ.
(. 6.4).
COM+
MSMQ
COM+
6.4. COM+
1.
, (recorder),
.
97
6. COM+
2. ,
,
MSMQ
.
3. MSMQ (listener),
COM+ .
COM+ , (listener helper),
.
4. (player),
,
.
.
: ,
.
(call-back object),
,
MSMQ
(, ), (. 6.5).
6.5.
COM+
- COM+ ( ).
98
6. COM+
,
COM+, .
,
COM+.
COM+
. COM+
.
COM+ .
COM+,
,
. COM+
.
Microsoft Windows.
, COM+
COM+ CLR
COM+ .NET,
CLR.
99
6. COM+
COM+ .NET Framework
COM+.
CLR COM+,
, COM+ (serviced
component), ( COM+) .
,
System.EnterpriseServices.ServicedComponent .
ServicedComponent
COM+. . 6.6.
.NET
Remoting
COM+
.NET Remoting (
BinaryFormatter), COM+
.
100
6. COM+
6.6, .NET Framework ,
, COM+. .NET
Enterpsise Services COM+,
COM+ .
, COM+
, ,
CLR COM+. ,
COM+, COM+
System.Runtime.InteropServices.COMException.
COM+,
, .
Unhandled Exception: System.Runtime.InteropServices.COMException (0x8000FFFF):
Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
Unhandled Exception: System.Runtime.InteropServices.COMException (0x8004D082):
Exception from HRESULT: 0x8004D082
.NET, , ,
.NET Remoting
, .NET
Remoting .
.NET Framework ,
System.EnterpriseServices.ServicedComponent,
public;
, , .
,
, COM+ , .
101
6. COM+
,
COM+.
public, .
System.EnterpriseServices, (TransactionAttribute),
(JustInTimeActivationAttribute
(SynchronizationAttribute).
ObjectPoolingAttribute)
JIT- ,
JIT- .
.
// SampleComponent.cs
using System;
using System.EnterpriseServices;
[assembly:
[assembly:
[assembly:
[assembly:
ApplicationAccessControl(false)]
ApplicationName("Serviced Component Example 01")]
Description("Sample of .NET serviced component.")]
ApplicationActivation(ActivationOption.Server)]
,
COM+. ApplicationActivation
.
namespace ServicedComponentSample
{
[JustInTimeActivation]
[Transaction(TransactionOption.Required)]
[ObjectPooling(Enabled=true, MinPoolSize=5, MaxPoolSize=10)]
public class SampleComponent: ServicedComponent
{
, ,
JIT-
public SampleComponent()
{
}
().
,
102
6. COM+
, -
.
Activate Deactivate, ,
.
protected override void Activate()
{
}
protected override void Deactivate()
{
//
//
}
CanBePooled true,
, .
protected override bool CanBePooled()
{
//
return true;
}
System.EnterpriseServices.AutoCompleteAttribute
. ,
, ,
.
[AutoComplete]
public void Do()
{
}
}
}
// SampleComponent.cs
AutoComplete
ContextUtil.
COM+, .
ContextUtil.SetComplete COM+ ,
ContextUtil.SetAbort .
.
103
6. COM+
try
{
...
ContextUtil.SetComplete();
}
catch()
{
ContextUtil.SetAbort();
}
ContextUtil ,
COM+ ,
COM+. ,
ContextUtil, , , AutoComplete,
.
, ,
COM+ COM+.
(strong-named assembly).
, .
, .
, .
sn.exe .NET
Framework
SDK.
SampleComponent.cs ( make-)
.
sn -k SampleComponent.snk
csc /target:library /r:System.EnterpriseServices.dll SampleComponent.cs
/keyfile:SampleComponent.snk
COM+.
.NET
Framework
System.EnterpriseServices.RegistrationHelper;
c regsvcs.exe;
.
104
6. COM+
.
.
regsvcs SampleComponent.dll
COM+ .
regsvcs /u SampleComponent.dll
.
// SampleClient.cs
using System;
using ServicedComponentSample;
class Test
{
static public void Main()
{
using(SampleComponent com = new SampleComponent())
{
com.Do();
}
}
}
// SampleClient.cs
using Dispose .
COM+.
.
csc /target:exe /r:SampleComponent.dll SampleClient.cs
SampleComponent.dll. ,
comexp.msc COM+,
SampleClient.exe. ,
COM+ ,
, .
105
6. COM+
.
,
,
.NET Remoting
BinaryFormatter. ,
,
System.Runtime.Serialization.Formatter.
FCL,
System.ApplicationException System.SystemException,
.
. ,
SoapFormatter
BinaryFormatter.
System.SystemException, .
// ComException.cs
using System;
using System.EnterpriseServices;
using System.Runtime.Serialization;
[assembly: ApplicationActivation(ActivationOption.Server)]
[assembly: ApplicationAccessControl(false)]
[Serializable]
public class CustomException: System.ApplicationException
{
public CustomException(SerializationInfo info, StreamingContext context):
base(info, context)
{
}
public CustomException(string message): base(message)
{
}
}
public class ComSample: ServicedComponent
{
public ComSample()
{
}
public void Process()
{
throw new CustomException(" ");
}
}
106
6. COM+
class MainApp
{
static public void Main()
{
ComSample com = new ComSample();
try
{
com.Process();
}
catch(CustomException e)
{
Console.WriteLine(": {0}", e.Message);
}
finally
{
com.Dispose();
}
}
} // ComException.cs
.
sn -k ComException.snk
csc ComException.cs /keyfile:ComException.snk /r:System.EnterpriseServices.dll
regsvcs ComException.exe
COM+ - , COM+.
System.EnterpriseServices.CompensatingResourceManager:
(log), ;
( Clerk), ;
( Compensator),
.
.
. ,
- , ,
,
. ,
107
6. COM+
.
. :
. .
,
. ,
,
.
( ) .
make-,
.NET SDK nmake.exe.
.
# : makefile
all: CrmSample.exe
#
CrmSample.key:
sn -k CrmSample.key
CrmSample.exe: CrmSample.cs CrmSample.Key
csc /r:System.EnterpriseServices.dll CrmSample.cs /keyfile:CrmSample.key
install:
# COM+
regsvcs CrmSample.exe
uninstall:
regsvcs u CrmSample.exe
COM+,
, sn.exe .NET SKD .
C# csc.exe , .
nmake install COM+
regsvcs.exe Microsoft Windows.
CrmSample.cs.
108
6. COM+
// CrmSample.cs
using System;
using System.IO;
using System.Collections.Generic;
using System.EnterpriseServices;
using System.EnterpriseServices.CompensatingResourceManager;
[assembly:
[assembly:
[assembly:
[assembly:
[assembly:
ApplicationActivation(ActivationOption.Server)]
ApplicationAccessControl(false)]
ApplicationCrmEnabled]
ApplicationName("Seva CRM")]
Description(" CRM")]
System.EnterpriseServices
COM+:
ApplicationActivation
COM+ (
);
ApplicationCrmEnabled CRM
COM+;
ApplicationAccessControl ,
;
System.ComponentModel.DescriptionAttribute .
StreamLog ,
.
public static class StreamLog
{
public static void Save(LogRecord log)
{
if (log.Record is object[])
{
object[] record = (object[])log.Record;
string fileName = (string) record[0];
byte[] buffer = (byte[]) record[1];
using (FileStream file = new FileStream(fileName,
FileMode.Create, FileAccess.Write))
{
file.Write(buffer, 0, buffer.Length);
}
}
} // Save()
} // StreamLog
StreamCache ,
.
109
6. COM+
public class StreamCache
{
private string fileName;
private MemoryStream stream;
public MemoryStream Stream
{
get { return stream;}
}
public string FileName
{
get { return fileName;}
}
public StreamCache(string streamFileName)
{
fileName = streamFileName;
stream = new MemoryStream();
}
Reopen .
MemoryStream,
, ,
.
public void Reopen()
{
if (!stream.CanRead)
{
stream.Close();
byte[] buffer = stream.ToArray();
stream.Dispose();
stream = new MemoryStream();
stream.Write(buffer, 0, buffer.Length);
stream.Seek(0, SeekOrigin.Begin);
}
} // Reopen()
Read,
MemoryStream.
public void Read()
{
byte[] buffer = new byte[32*1024];
using (Stream inputStream = new FileStream(fileName,
FileMode.Open, FileAccess.Read))
{
110
6. COM+
while (true)
{
int read = inputStream.Read(buffer, 0, buffer.Length);
if (read <= 0)
{
break;
}
Stream.Write(buffer, 0, read);
}
}
} // Read()
} // StreamCache
StreamCrm , COM+.
COM+ ,
COM+ .
.
public class StreamCrm: ServicedComponent
{
private Dictionary<string, StreamCache> cache;
public StreamCrm()
{
cache = new Dictionary<string, StreamCache>();
}
StreamCrm.CheckCache , .
,
StreamCache.Reopen.
private StreamCache CheckCache(string fileName, bool read)
{
StreamCache streamCache;
string key = Path.GetFullPath(fileName).ToLower();
if (!cache.ContainsKey(key))
{
streamCache = new StreamCache(fileName);
cache.Add(key, streamCache);
if (read)
{
streamCache.Read();
};
}
else
{
streamCache = cache[key];
streamCache.Reopen();
};
return streamCache;
}
111
6. COM+
StreamCrm.ReadFromFile , ,
StreamCrm.WriteToFile .
public MemoryStream ReadFromFile(string fileName)
{
return CheckCache(fileName, true).Stream;
}
public MemoryStream WriteToFile(String fileName)
{
return CheckCache(fileName, false).Stream;
}
StreamCrm.Flush ,
,
.
public object[] Flush(String fileName)
{
StreamCache streamCache = CheckCache(fileName, false);
streamCache.Stream.Close();
object[] record = new object[2];
record[0] = fileName;
record[1] = streamCache.Stream.ToArray();
return record;
}
StreamCrm.CreateClerk
.
.
public static Clerk CreateClerk()
{
return new Clerk(typeof(StreamCompensator), "Compensator",
CompensatorOptions.AllPhases);
}
}
StreamCompensator Compensator
.
public class StreamCompensator :
System.EnterpriseServices.CompensatingResourceManager.Compensator
{
private bool prepared = false;
112
6. COM+
c Prepare
. PrepareRecord false,
, PrepareRecord.
public override void BeginPrepare ()
{
}
public override bool PrepareRecord(LogRecord log)
{
prepared = false;
if (!(log.Record is object[]))
return true;
object[] record = log.Record as object[];
if (record.Length != 2)
return true;
if (!(record[0] is string) || !(record[1] is byte[]))
return true;
prepared = true;
return false;
}
EndPrepare .
true, .
public override bool EndPrepare ()
{
return prepared;
}
c Commit .
CommitRecord ,
.
public override void BeginCommit (bool commit)
{
}
public override bool CommitRecord (LogRecord log)
{
StreamLog.Save(log);
return true;
}
public override void EndCommit ()
{
}
Abort
.
113
6. COM+
,
.
public override void BeginAbort (bool abort)
{
}
public override bool AbortRecord (LogRecord log)
{
return true;
}
public override void EndAbort ()
{
}
} // StreamCrm
COM+,
. , COM+
. TransactionAttribute
COM+. SampleCrmClient2
ReadLine,
.
[Transaction(TransactionOption.Required)]
public class SampleCrmClient2: ServicedComponent
{
public SampleCrmClient2()
{
}
public string ReadLine(StreamCrm crm, string fileName)
{
using (StreamReader reader = new StreamReader(crm.ReadFromFile(fileName)))
{
return line = reader.ReadLine();
}
}
}
SampleCrmClient.DoSomeWork CRM.
, COM+
%systemroot%\system32.
114
6. COM+
[Transaction(TransactionOption.RequiresNew)]
public class SampleCrmClient1: ServicedComponent
{
public SampleCrmClient1()
{
}
public void DoSomeWork(string dir)
{
const string fileName1 = "sample1.txt";
const string fileName2 = "sample2.txt";
Environment.CurrentDirectory = dir;
StreamCrm crm = new StreamCrm();
Clerk clerk = StreamCrm.CreateClerk();
. ,
, .
,
StreamCrm.Flush. ,
.
using (StreamWriter writer = new StreamWriter(crm.WriteToFile(fileName1)))
{
writer.Write(Environment.CurrentDirectory);
}
//
clerk.WriteLogRecord(crm.Flush(fileName1));
COM+
SampleCrmClient2. ,
,
, , ,
.
String tempString = "";
using (SampleCrmClient2 client2 = new SampleCrmClient2())
{
tempString = client2.ReadLine(crm, Path.GetFullPath(fileName1));
}
.
using (StreamWriter writer = new StreamWriter(crm.WriteToFile(fileName2)))
{
writer.WriteLine(String.Format(" [{0}]:", fileName1));
writer.WriteLine(tempString);
}
115
6. COM+
//
clerk.WriteLogRecord(crm.Flush(fileName2));
// ,
ContextUtil.SetComplete();
}
}
EnterpriseServices/COM+ Dispose (
using) .
class CrmTest
{
public static void Main()
{
SampleCrmClient1 client1 = new SampleCrmClient1();
try
{
client1.DoSomeWork(Environment.CurrentDirectory);
}
finally
{
client1.Dispose();
}
}
}
,
, ,
IDisposable
Dispose ( ) .
(. 6.7):
, ;
(event class),
, ;
;
COM+;
116
6. COM+
,
.
( )
COM+
COM+
6.7.
, -.
, .
// LceEvents.cs
using System;
using System.Runtime.InteropServices;
using System.EnterpriseServices;
public static class EventsGuids
{
public const string interfaceId = "A5105B2C-40BF-46C6-B19C-4286A423DBF9";
public const string eventClassId = "DF64D391-CCE9-4FC6-B5F2-3F4DE3FA48C2";
}
[Guid(EventsGuids.interfaceId)]
public interface ILceMessage
{
void TriggerEvent(string message);
}
// LceEvents.cs
, .
117
6. COM+
// LcePublisher.cs
using
using
using
using
System;
System.Threading;
System.Runtime.InteropServices;
System.EnterpriseServices;
, EventClassAttribute
.
, .
[EventClass]
[Guid(EventsGuids.eventClassId)]
[Transaction(TransactionOption.Disabled)]
public class LceEvents: ServicedComponent, ILceMessage
{
public void TriggerEvent(string message)
{
}
}
,
COM+. ,
COM+.
public class LcePublisher: ServicedComponent
{
public LcePublisher()
{
}
public void DoWork()
{
ILceMessage lcEvent = (ILceMessage) new LceEvents();
try
{
while (true)
{
lcEvent.TriggerEvent("!");
Thread.Sleep(1000);
}
}
catch (System.Runtime.InteropServices.COMException)
{
Console.WriteLine(" ");
}
}
}
118
6. COM+
class MainApp
{
public static void Main()
{
LcePublisher com = new LcePublisher();
com.DoWork();
}
}
// LcePublisher.cs
COM+, .
.
, .
,
.
// LceSubscriber.cs
using System;
using System.IO;
using System.Threading;
using System.Runtime.InteropServices;
using System.EnterpriseServices;
using System.Messaging;
using Seva.ComUtils;
using Seva.Msmq;
[assembly: ApplicationName("LCE demo")]
[assembly: ApplicationActivation(ActivationOption.Server)]
[assembly: ApplicationAccessControl(false)]
public static class Consts
{
public const string testQueue = @".\Private$\sample_queue";
}
[JustInTimeActivation]
[Transaction(TransactionOption.Required)]
public class LceSubscriber : ServicedComponent, ILceMessage
{
public LceSubscriber()
{
}
,
.
119
6. COM+
public void TriggerEvent(string message)
{
MessageQueue queue = MsmqTools.CreateQueue(Consts.testQueue);
queue.Send(message, MessageQueueTransactionType.Automatic);
ContextUtil.SetComplete();
}
}
class MainApp
{
public static void Main()
{
//
//
LceSubscriber subscriber = new LceSubscriber();
//
LceUtils.PermanentSubscription(Consts.comAppName,
typeof(LceSubscriber).ToString(),
EventsGuids.eventClassId, EventsGuids.interfaceId);
}
}
// LceSubscriber.cs
Make- .
all: LceSubscriber.exe LcePublisher.exe
LceSubscriber.snk:
sn -k LceSubscriber.snk
LcePublisher.snk:
sn -k LcePublisher.snk
LceSubscriber.exe: Seva*.cs LceEvents.cs LceSubscriber.cs LceSubscriber.snk
csc /out:LceSubscriber.exe Seva*.cs LceEvents.cs LceSubscriber.cs
/r:interop.comadmin.dll /keyfile:LceSubscriber.snk
LcePublisher.exe: Seva*.cs LceEvents.cs LcePublisher.cs LcePublisher.snk
csc /out:LcePublisher.exe Seva*.cs LceEvents.cs LcePublisher.cs
/r:interop.comadmin.dll /keyfile:LcePublisher.snk
COM+ COM+
(SWC) COM+
COM+ ServicedComponent.
SWC TCP/IP
.
Windows 2003 Windows XP SP2, .
NAT, .
%systemroot%\system32\Com\comexp.msc
:
120
6. COM+
REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSDTC\Security]
"NetworkDtcAccess"=dword:00000001
net stop MSDTC
net start MSDTC
, SWC. COM+
,
System.IDisposable void Dispose(),
COM+.
using System;
using System.EnterpriseServices;
namespace Seva.Swc
{
public class SwcUtil : IDisposable
{
public SwcUtil()
{
ServiceDomain.Enter(GetConfig(TransactionOption.Required));
}
public SwcUtil(TransactionOption transactionOption)
{
ServiceDomain.Enter(GetConfig(transactionOption));
}
protected virtual ServiceConfig GetConfig(
TransactionOption transactionOption)
{
ServiceConfig config = new ServiceConfig();
config.Transaction = transactionOption;
config.TrackingEnabled = true;
config.TrackingAppName = "SwcUtil";
config.TrackingComponentName = this.GetType().FullName;
}
return config;
.
COM+.
121
6. COM+
using System;
using System.EnterpriseServices;
using System.Messaging;
using Seva.Msmq;
using Seva.Swc;
public class MainApp
{
public static void Main()
{
using (SwcUtil swc = new SwcUtil())
{
MessageQueue queue = MsmqTools.CreateQueue(@".\Private$\swc_queue");
queue.Send("SWC Message", MessageQueueTransactionType.Automatic);
Console.WriteLine(" <Enter> ");
Console.ReadLine();
ContextUtil.SetComplete();
}
}
}
SWC ,
COM+.
, SWC
-,
System.EnterpriseServices.ServicedComponent,
Compensator
, COM+.
Clerk
catastrophic exception,
, . ,
, ,
, MSMQ MS SQL.
6.4.
COM+
, .
1. COM+ .NET Framework, Enterprise Services
.NET Framework,
. Enterprise Services
122
6. COM+
,
CLR COM+.
2. COM+ ,
, , RPC (135-
TCP). , ,
.
COM+
.
1. . COM+ Microsoft
Windows 2000
Windows.
COM+. , Enterprise Services .
2. . COM+
Windows Server.
,
JIT-. COM+
,
.
3. . COM+
Microsoft (MTS)
.
4. . COM+
(DNS NETBIOS), COM+.
, (
COM+).
Windows
Clustering,
,
123
6. COM+
. , COM+
.
5. ( ). COM+ .Net
,
.
6. . COM+
Microsoft Windows.
, EnterpriseServices/COM+
,
, Microsoft Windows
.
124
7. - ASP.NET
7. - ASP.NET
7.1.
Interoperability),
ASP.NET
SOAP
SOAP-
SOAP-
SOAP
7.1. - ASP.NET
, -
125
7. - ASP.NET
SOAP,
SOAP, -
.
- ,
SOAP. SOAP,
(pipeline), SOAP.
.NET Framework 2.0 HTTP
SOAP - ASP.NET,
SOAP , WSE (Web Service
Enhancements).
- ASP.NET,
, Microsoft
Internet Information Services, IIS (. 7.2) .
ASP.NET +WSE
SOAP
SOAP
IIS / http.sys
HTTP
WSE 3.0
TCP/IP
TCP/IP
TCP, WSE
7.2. -
126
7. - ASP.NET
WSE 3.0 - TCP
IIS. II ASP.NET
IIS.
- ASP.NET , .NET
Framework, ,
-. .NET Framework WSDL-
-,
. .NET Framework
-, - ASP.NET. ,
CLI Mono
- ASP.NET ( 1.1 2.0)
Apache XSP.
-
. ,
-, ,
. , WS-Transaction
WS-BusinessActivity,
, -.
, , , .NET Framework
3.0. - ASP.NET
, , .
- ,
,
. UDDI (Universal Description,
Discovery, and Integration), WS-I
- .
- Microsoft Windows
2003 J2EE.
-,
2005-
127
7. - ASP.NET
, -,
UDDI . ,
- .
7.2.
WSE
TCP. WSE
-,
,
SOAP-,
SOAP.
(pipeline), . 7.3.
WSE
WSE
7.3 WSE
128
7. - ASP.NET
WSE (policy)
- .
-.
(assertions
extensions),
.
WSE (
) , (
).
-
( 7.4). ,
( wse3policyCache.config),
(web.config) .
WseConfigEditor3.exe .
WSE
WSE
app.exe.config
web.config
wse3policyCache.config
wse3policyCache.config
7.4 WSE
web.config WSE.
<system.web><webServices><soapServerProtocolFactory> WSE
SOAP.
<microsoft.web.services3><diagnostics>
,
.
129
7. - ASP.NET
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<webServices>
<soapServerProtocolFactory type="Microsoft.Web.Services3.WseProtocolFactory,
Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
</webServices>
<compilation debug="false">
<assemblies>
<add assembly="Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" />
</assemblies>
</compilation>
</system.web>
<microsoft.web.services3>
<diagnostics>
<trace enabled="true" input="C:\Inetpub\logs\InputTrace.webinfo"
output="C:\Inetpub\logs\OutputTrace.webinfo" />
</diagnostics>
<policy fileName="wse3policyCache.config" />
</microsoft.web.services3>
</configuration>
.
7.3.
- .NET Framework
, -
. - ASP.NET
. ,
SOAP ASP.NET .
-
ASP.NET IIS ( C:\Inetpub\wwwroot\)
.asmx .
<%@ WebService class="SampleService" language="C#" %>
, URL
SOAP/HTTP - SampleService.
- ,
bin. - .
130
7. - ASP.NET
-
System.Web.Services.WebServiceAttribute,
Description Namespace
, -
WSDL. URI,
-.
URL.
System.Web.Services.WebService.
-
WSE
3.0
Microsoft.Web.Services3.PolictyAttribute, ,
.
, - ,
System.Web.Services.WebMethodAttribute.
Description TransactionOption. -
.
COM+. , -
, .
- .NET Framework 2.0 / WSE 3.0
. - .
<%@ WebService class="BankAccount" language="C#" %>
using
using
using
using
System;
System.Web.Services;
System.EnterpriseServices;
Microsoft.Web.Services3;
[WebService(Namecpace=http://super.bank/webservices)]
[Policy(BankAccountService)]
public class BankAccount : WebService
{
[WebMethod(TransactionOption=TransactionOption.RequiresNew]
public void Transfer(double Amount)
{
// ...
//
ContextUtil.SetComplete();
}
}
131
7. - ASP.NET
- SoapRpcMethodAttribute
SoapDocumentMethodAttribute.
WSDL. , SoapDocumentMethodAttribute
SOAP-Document, ,
SoapRpcMethodAttribute
SOAP-RPC, . ,
SOAP
XmlSerializer,
- ,
XmlSerializer. SoapDocumentMethod SoapRpcMethod
OneWay,
.
-
WSE 3.0
WseWsdl3.exe. .
WseWsdl3.exe http://localhost/service.asmx?wsdl /type:webClient /out:proxy.cs
URL WSDL-
proxy.cs
-,
Microsoft.Web.Services3.WebServicesClientProtocol. -
WSDL ASP.NET -.
c ,
- . ,
WSE
.
[Policy("BankClientPolicy")]
public partial class BankService :
Microsoft.Web.Services3.WebServicesClientProtocol
{
}
, , xsd.exe
XML-, ,
132
7. - ASP.NET
. CLR
XSD- ,
(. 7.5).
ASP.NET
WSDL-
WseWsdl3.exe
wsdl.exe
7.5. -
- .
, Transfer, :
Transfer -;
BeginTransfer EndTransfer
BeginInvoke/EndInvoke;
TransferAsync ( )
InvokeAsync.
BeginInvoke/EndInvoke/InvokeAsync
, .
CancelAsync ( -)
InvokeAsync.
WseWsdl3.exe
.
wsdl.exe .NET SDK, WSE,
.
, .
7.4.
WSE
-
ASP.NET WSE, -
133
7. - ASP.NET
( 10 8 ).
SOAP
Microsoft.Web.Services3.Design.PolicyAssertion.
// TimeAssertion.cs
using System;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Xml.Serialization;
using System.Collections.Generic;
using Microsoft.Web.Services3;
using Microsoft.Web.Services3.Design;
using Microsoft.Web.Services3.Security;
[assembly:AssemblyVersionAttribute("1.0.0.0")]
namespace Seva.WS.Assertions
{
public class TimeAssertion: PolicyAssertion
{
private TimeIntervals intervals;
public TimeAssertion(): base()
{
intervals = null;
}
ReadXml .
.
public override void ReadXml(XmlReader reader,
IDictionary<string, Type> extensions)
{
string fileName = reader.GetAttribute("file");
if (fileName == null)
throw new Exception("Attribute 'file' not found in policy");
// - ,
//
reader.Read();
//
using (StreamReader timeReader = new StreamReader(fileName))
{
XmlSerializer serializer = new
XmlSerializer(typeof(TimeIntervals));
intervals = (TimeIntervals) serializer.Deserialize(
new XmlTextReader(timeReader));
}
}
134
7. - ASP.NET
Create....Filter SOAP,
.
CreateServiceInputFilter ,
.
public override SoapFilter CreateClientInputFilter(
FilterCreationContext context)
{
return null;
}
public override SoapFilter CreateClientOutputFilter(
FilterCreationContext context)
{
return null;
}
public override SoapFilter CreateServiceInputFilter(
FilterCreationContext context)
{
return new CheckTimeFilter(intervals, context);
}
public override SoapFilter CreateServiceOutputFilter(
FilterCreationContext context)
{
return null;
}
}
Microsoft.Web.Services3.SoapFilter
. ,
.
public class CheckTimeFilter : SoapFilter
{
private TimeIntervals intervals;
public CheckTimeFilter(TimeIntervals intervals,
FilterCreationContext context)
{
this.intervals = intervals;
}
ProcessMessage , SOAP.
SoapEnvelope.
135
7. - ASP.NET
public override SoapFilterResult ProcessMessage(SoapEnvelope envelope)
{
if (! intervals.Check(DateTime.Now))
throw new Exception("Service is unavailable now.");
return SoapFilterResult.Continue;
}
}
TimeInterval . TimeSpan,
DateTime,
XML,
,
.
<TimeInterval Inverse="false" From="09:00:00" To="10:30:00" />
XML
, XML-.
[Serializable]
public class TimeInterval
{
[XmlAttribute("From")]
public string FromField
{
set {From = TimeSpan.Parse(value);}
get {return From.ToString();}
}
[XmlAttribute("To")]
public string ToField
{
set {To = TimeSpan.Parse(value);}
get {return To.ToString();}
}
[XmlAttribute("Inverse")]
public bool Inverse;
[XmlIgnore]
public TimeSpan From;
[XmlIgnore]
public TimeSpan To;
public bool Check(DateTime Time)
{
bool result = (From <= Time.TimeOfDay) && (Time.TimeOfDay <= To);
if (Inverse)
result = ! result;
return result;
}
}
136
7. - ASP.NET
TimeIntervals
.
[XmlRoot("TimeIntervals")]
public class TimeIntervals: List<TimeInterval>
{
public TimeIntervals()
{
}
public bool Check(DateTime Time)
{
foreach (TimeInterval interval in this)
if (interval.Check(Time))
return true;
return false;
}
}
}
WSE GAC.
make- GAC
nmake && nmake install.
# : makefile
all: Seva.WS.TimeAssertion.dll
Seva.WS.TimeAssertion.dll: TimeAssertion.cs TimeAssertion.key
csc /t:library /out:Seva.WS.TimeAssertion.dll /keyfile:TimeAssertion.key
/r:Microsoft.Web.Services3.dll TimeAssertion.cs
TimeAssertion.key:
sn -k TimeAssertion.key
install:
gacutil -nologo -i Seva.WS.TimeAssertion.dll`
.
1. -,
.
<?xml version="1.0" encoding="utf-8"?>
<TimeIntervals>
<TimeInterval Inverse="true" From="09:00:00" To="20:00:00" />
<TimeInterval Inverse="false" From="13:00:00" To="13:30:00" />
</TimeIntervals>
2. wse3policyCache.config (
,
WSE).
137
7. - ASP.NET
<policies xmlns="http://schemas.microsoft.com/wse/2005/06/policy">
<extensions>
<extension name="timeIntervals" type="Seva.WS.Assertions.TimeAssertion,
Seva.WS.TimeAssertion, Version=1.0.0.0, Culture=neutral, PublicKeyToken=..." />
</extensions>
<policy name="MyServicePolicy">
<timeIntervals file="C:\Inetpub\wwwroot\timeschema.config" />
</policy>
</policy>
</policies>
MyServicePolicy ,
Policy -.
7.5.
WSE ,
- , :
X.509;
,
( ) (
TCP).
WseConfigEditor3.exe WSE.
WSE
Windows, .
-
. WSE
(Microsoft.Web.Services3.Design.TokenProvider).
SOAP,
WSE. , ,
UsernameOverTransportAssertion
UsernameForCertificateAssertion,
.
138
7. - ASP.NET
web.config
<microsoft.web.services3><security><securityTokenManager>.
, localName,
.
<microsoft.web.services3>
<security>
<securityTokenManager>
<add localName="UsernameToken" type="Seva.WS.Users.UsersListManager,
Seva.WS.UsersManager, Version=1.0.0.0, Culture=neutral, PublicKeyToken=..."
namespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecuritysecext-1.0.xsd" >
<users file="C:\Inetpub\users.config"/>
</add>
</securityTokenManager>
</security>
<policy fileName="wse3policyCache.config" />
</microsoft.web.services3>
SOAP ( <wsse:Security>)
, VerifyToken.
UsernameTokenManager, SOAP
<wsse:UsernameToken>.
UsernameTokenManager, ,
SecurityTokenManager.
, UsernameTokenManager
, AuthenticateToken
, SOAP.
, , .
(),
. AuthenticateToken .
, SOAP
( , ,
X.509) , (digest).
, (nonce),
:
Password_Digest = Base64(SHA1( nonce + created + password)),
139
7. - ASP.NET
SHA1 .
-. ,
, .
SSL.
,
( VerifyPlainTextPassword). ,
, .
,
.
SOAP <wsse:UsernameToken>,
UsernameToken PasswordOption.SendHashed.
- .
// UsersManager.cs
using System;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Security;
using
using
using
using
Microsoft.Web.Services3;
Microsoft.Web.Services3.Design;
Microsoft.Web.Services3.Security;
Microsoft.Web.Services3.Security.Tokens;
WSE
GAC, .
140
7. - ASP.NET
[assembly:AssemblyVersionAttribute("1.0.0.0")]
namespace Seva.WS.Users
{
public class UsersListManager: UsernameTokenManager
{
private UsersList users;
public UsersListManager()
{
users = new UsersList();
}
UsersListManager
AuthenticateToken.
public UsersListManager(XmlNodeList configData): base(configData)
{
string fileName = configData[0].Attributes["file"].Value;
users = UsersList.Load(fileName);
}
protected override string AuthenticateToken(UsernameToken token)
{
if (!users.Users.ContainsKey(token.Username))
return null;
return users.Users[token.Username];
}
VerifyPlainTextPassword .
protected override void VerifyPlainTextPassword(UsernameToken token,
string authenticatedPassword)
{
if (token==null)
throw new ArgumentNullException("token is null");
String hashed = Utils.HashedPassword(token.Password);
if (authenticatedPassword==null || authenticatedPassword=="" ||
hashed!=authenticatedPassword)
throw new Exception("Passwords does not match ");
UsersList.
XmlSerialiser,
IXmlSerializable.
141
7. - ASP.NET
[XmlRoot("users")]
public class UsersList: IXmlSerializable
{
private Dictionary<string, string> usersField;
public Dictionary<string, string> Users
{
get {return usersField;}
}
public UsersList()
{
usersField = new Dictionary<string, string>();
}
public void ReadXml(XmlReader reader)
{
reader.Read();
while (reader.NodeType != XmlNodeType.EndElement)
{
Users.Add(reader.GetAttribute("username"),
reader.GetAttribute("password"));
reader.Read();
}
}
public void WriteXml(XmlWriter writer)
{
foreach (string user in Users.Keys)
{
writer.WriteStartElement("user");
writer.WriteAttributeString("username", user);
writer.WriteAttributeString("password", this.Users[user]);
writer.WriteEndElement();
}
}
public XmlSchema GetSchema()
{
return null;
}
NewUser .
public void NewUser(string userName, string password, bool hashed)
{
if (Users.ContainsKey(userName))
{
throw new ApplicationException("Duplicate username.");
}
if (hashed)
{
password = Utils.HashedPassword(password);
}
Users.Add(userName, password);
}
142
7. - ASP.NET
Load Save ( )
.
public static UsersList Load(string fileName)
{
XmlSerializer serializer = new XmlSerializer(typeof(UsersList));
using (StreamReader reader = new StreamReader(fileName))
{
return (UsersList) serializer.Deserialize(reader);
};
}
public void Save(string fileName)
{
XmlSerializer serializer = new XmlSerializer(typeof(UsersList));
using (StreamWriter writer = new StreamWriter(fileName))
{
serializer.Serialize(writer, this);
};
}
}
Utils
.
static class Utils
{
public static string HashedPassword(string password)
{
SHA1CryptoServiceProvider crypto = new SHA1CryptoServiceProvider();
byte[] inputBuffer = Encoding.Unicode.GetBytes(password);
return Convert.ToBase64String(crypto.ComputeHash(inputBuffer));
}
}
make- c
GAC nmake && nmake install.
all: Seva.WS.UsersManager.dll
Seva.WS.UsersManager.dll: UsersManager.cs UsersManager.key
csc /t:library /out:Seva.WS.UsersManager.dll /keyfile:TimeAssertion.key
/r:Microsoft.Web.Services3.dll UsersManager.cs
UsersManager.key:
sn -k UsersManager.key
install:
gacutil -nologo -i Seva.WS.UsersManager.dll
(web.config)
<microsoft.web.services3> <security>.
143
7. - ASP.NET
<?xml version="1.0" encoding="utf-8"?>
<configuration>
...
<microsoft.web.services3>
<security>
<securityTokenManager>
<add type="Seva.WS.Users.UsersListManager, Seva.WS.UsersManager,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=..."
namespace=
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
localName="UsernameToken">
<users file="C:\Inetpub\users.config"/>
</add>
</securityTokenManager>
</security>
<policy fileName="wse3policyCache.config" />
</microsoft.web.services3>
</configuration>
,
.
<policy><authorization> -
, <allow> <deny>.
UsernameClientAssertion.
-,
X.509. X.509
.
[XmlRoot("user")]
public struct UserCredential
{
[XmlAttribute("username")]
public string Username;
[XmlAttribute("password")]
public string Password;
}
public class UsernameClientAssertion: SecurityPolicyAssertion
{
private UserCredential credential;
public UsernameClientAssertion()
{
}
ReadXml ,
.
144
7. - ASP.NET
.
(,
) -
.
public override void ReadXml(XmlReader reader,
IDictionary<string, Type> extensions)
{
string fileName = reader.GetAttribute("file");
if (fileName == null)
throw new Exception("Attribute 'file' not found in policy");
// -
reader.Read();
using (StreamReader stream = new StreamReader(fileName))
{
XmlSerializer serializer = new
XmlSerializer(typeof(UserCredential));
using (XmlTextReader xmlReader = new XmlTextReader(stream))
{
credential = (UserCredential) serializer.Deserialize(xmlReader);
}
}
}
CreateClientOutputFilter SOAP,
.
public override SoapFilter CreateClientOutputFilter(
FilterCreationContext context)
{
return new UsernameClientFilter(this, credential, context);
}
public override SoapFilter CreateClientInputFilter(
FilterCreationContext context)
{
return null;
}
public override SoapFilter CreateServiceInputFilter(
FilterCreationContext context)
{
return null;
}
public override SoapFilter CreateServiceOutputFilter(
FilterCreationContext context)
{
return null;
}
}
145
7. - ASP.NET
SendSecurityFilter
SecureMessage.
class UsernameClientFilter : SendSecurityFilter
{
private UserCredential credential;
public UsernameClientFilter(UsernameClientAssertion assertion,
UserCredential credential, FilterCreationContext filterContext)
: base(assertion.ServiceActor, true, assertion.ClientActor)
{
this.credential = credential;
}
public override void SecureMessage(SoapEnvelope envelope,
Security security)
{
UsernameToken userToken = new UsernameToken(credential.Username,
credential.Password, PasswordOption.SendHashed);
security.Tokens.Add(userToken);
}
}
}
.
// AddUser.cs
using System;
using System.IO;
using Seva.WS.Users;
class MainApp
{
public static int Main(string[] Args)
{
if (Args.Length < 3)
{
Console.WriteLine(
"usage: adduser <users' file> <username> <password> [--hashed]");
return 1;
}
UsersList users = new UsersList();
string fileName = Args[0];
if (File.Exists(fileName))
{
users = UsersList.Load(fileName);
}
bool hashed = false;
if (Args.Length==4)
{
hashed = Args[3]=="--hashed";
}
146
7. - ASP.NET
users.NewUser(Args[1], Args[2], hashed);
users.Save(fileName);
return 0;
}
}
WSE
UsernameOverTransportAssertion
,
wse3policyCache.config .
<policies xmlns="http://schemas.microsoft.com/wse/2005/06/policy">
<extensions>
<extension name="usernameOverTransportSecurity"
type="Microsoft.Web.Services3.Design.UsernameOverTransportAssertion,
Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
<extension name="requireActionHeader"
type="Microsoft.Web.Services3.Design.RequireActionHeaderAssertion,
Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
</extensions>
<policy name="ServicePolicy">
<usernameOverTransportSecurity />
<requireActionHeader />
</policy>
</policies>
UsernameClientAssertion
.
<policies xmlns="http://schemas.microsoft.com/wse/2005/06/policy">
<extensions>
<extension name="simpleUserName" type="Seva.WS.Users.UsernameClientAssertion,
Seva.WS.UsersManager, Version=1.0.0.0, Culture=neutral, PublicKeyToken=..."/>
</extensions>
<policy name="ClientPolicy">
<simpleUserName file="user.xml"/>
</policy>
</policies>
user.xml -.
<user username="user2" password="222" />
, , X.509
UsernameForCertificateAssertion
UsernameClientAssertion ,
.
UsernameForCertificateAssertion
147
7. - ASP.NET
, .
WseConfigEditor3.exe.
7.6.
-
. .NET
WSE
. -
.
1. . -
.
TCP/IP, NAT ,
HTTP. -
.
2. , . -
,
IIS ,
-.
.
3. .
WSE
WS-Security
1.1
,
.
4. .
-
- . - .NET
, , .NET Framework 3.0 WCF.
148
7. - ASP.NET
5. ( ). SOAP
,
-.
- , ,
.
WSE
.
WS-* -
. - ASP.NET
,
TCP/IP.
149
8. .NET Remoting
8. .NET Remoting
.NET Remoting,
.
.NET Remoting .
8.1.
.NET Remoting
, ,
.NET Remoting .NET. Remoting
,
. Remoting
.
Remoting
- SOAP,
(. 8.1).
SOAP-
.NET
Remoting
.NET
Remoting
HTTP / SOAP
TCP /
HTTP / SOAP
.NET Remoting
8.1. Remoting
150
8. .NET Remoting
, .NET
Remoting .NET Framework
COM+ .NET Enterprise Services.
Remoting, CLR .
1. , .
,
. ,
. ,
,
.
2. , .
System.MarshalByRefObject.
, ,
.
Remoting. Remoting
: ,
, .
3. ,
, .
. , ,
Remoting
.
, Remoting
CLR. MSMQ COM+,
Remoting - Microsoft
Windows. Remoting
CLI,
System.EnterpriseServices System.Messaging. ,
Remoting CLI
151
8. .NET Remoting
Microsoft (.NET Framework, .NET Compact Framework),
CLI ( Mono Project DotGNU
Portable.NET).
Remoting CLI
. Remoting
Enterprise Services. Remoting
COM+,
. Remoting -
,
- Remoting, Internet
Information Services (IIS).
8.2.
.NET Remoting
Remoting ,
Remoting . ,
, Remoting
(, MSMQ)
(, CLR COM+).
. , Remoting
, ,
, ,
, , .
152
8. .NET Remoting
.Net Remoting
.Net Remoting
.Net Remoting
.Net Remoting
TransparentProxy RealProxy.
153
8. .NET Remoting
. ,
,
( IMessage).
- ,
Remoting .
2. (channel) Remoting.
(sinks) . ,
,
-, ,
. , ,
, .
. ,
.
( ) IMessageSink.
(message sinks).
,
(channel sinks). IlientChannelSink
IServerChannelSink .
, ,
.
3.
ChannelServices.DispatchMessage) .
4. , Remoting,
. IChannel, IChannelSender,
IChannelReceiver
/ , . Remoting
. HttpChannel TcpChannel
HTTP TCP , .NET Framework 2.0
154
8. .NET Remoting
IpcChannel
(IPC: inter-process communication) .
: BinaryFormatter SoapFormatter.
System.Runtime.Remoting.ObjRef.
.
System.MarshalByRefObject Remoting
ObjRef,
Remoting
(. 8.3).
.NET
Remoting
Remoting
ObjRef
Remoting
.NET Remoting
8.3. Remoting
Remoting
,
MarshalByRefObject.
155
8. .NET Remoting
OneWayAttribute2. -
, .
. Remoting
,
, . Remoting
.
.
, ,
. Remoting
(lease),
. ,
,
.
,
(
set get ). , ,
, .
8.3.
.NET Remoting
Remoting
XML-. Remoting :
(, TCP);
BeginInvoke ,
156
8. .NET Remoting
Remoting
, .
,
.
,
Remoting
Remoting
(. 8.4).
.Net Remoting
.NET Remoting
.NET Remoting
RemoteWorker worker =
new RemoteWorker();
results = worker.DoWork();
RemoteWorker
RemoteReport report =
new RemoteReport();
report.ReportResults(results);
RemoteWorker
.NET Remoting
.Net Remoting
.Net Remoting
8.4. Remoting
, ,
, Remoting.
IIS, ,
.
.NET Remoting.
157
8. .NET Remoting
// server.cs
using System;
using System.Runtime.Remoting;
using System.Configuration;
public class Server
{
public static void Main(string[] args)
{
string config = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
Console.WriteLine(config);
RemotingConfiguration.Configure(s);
// .NET Framework 2.0
// RemotingConfiguration.Configure(s, false);
Console.WriteLine(" ENTER .");
Console.ReadLine();
}
}
,
Remoting .
Remoting, .
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown mode="SingleCall"
type="RemoteTest.TestService, RemoteTestService"
objectUri="endpoint"/>
</service>
<channels>
<channel ref="tcp" port="2080" />
</channels>
</application>
</system.runtime.remoting>
</configuration>
<application> <service> .
, (
, ), URI,
. , ,
<wellknown mode="SingleCall" type=...
<wellknown mode="Singletone" type=...
. , ,
.
<activated type=...
158
8. .NET Remoting
<application><channels>
. ,
,
.
.
<configuration>
<system.runtime.remoting>
<application>
<client>
<wellknown mode="SingleCall"
type="RemoteTest.TestService, RemoteTestService"
objectUri="tcp://127.0.0.1:2080/endpoint" />
</client >
</application>
</system.runtime.remoting>
</configuration>
<application><client> .
, <service>,
<client>. Remoting
.
, , Remoting.
<client> ,
.
using System;
using System.Runtime.Remoting;
using RemotingTest;
public class Client
{
public static void Main(string[] args)
{
string config = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
Console.WriteLine(config);
RemotingConfiguration.Configure(config);
//
// ,
TestService service = new RemotingTest.TestService();
159
8. .NET Remoting
//
Console.WriteLine(service.Sum(2, 2));
.
,
.
// TestService.cs
using System;
namespace RemotingTest
{
public class TestService : MarshalByRefObject
{
public TestService()
{
Console.WriteLine("[ctor]");
}
~TestService()
{
Console.WriteLine("[dtor]");
}
public int Sum(int a, int b)
{
return a + b;
}
}
}
make- .
, CLI
System.Runtime.Remoting.dll. .NET Framework 2.0
C# (csc.rsp).
makefile : Server.exe Client.exe
Server.exe : Server.cs
csc Server.cs
Client.exe : Client.cs RemoteTestService.dll
csc /r:RemoteTestService.dll Client.cs
RemoteTestService.dll: TestService.cs
csc /out:RemoteTestService.dll /t:library TestService.cs
8.4.
- .NET Remoting
Remoting
. ,
160
8. .NET Remoting
, .
System.Activator, - Remoting
SOAP,
- WSDL. -
, , ,
,
.
SoapFormatter, HttpChannel
Remoting -
SOAP, WSDL SOAP-RPC ( SOAP-Document,
ASP.NET). ,
,
System.Runtime.Remoting.MetadataServices.MetaData,
-. soapsuds.exe.
,
System.Runtime.Remoting.Services.RemotingClientProxy,
Remotig.
soapsuds.exe -url:http://localhost:2080/endpoint?wsdl -gc
, -
( ,
soapsuds.exe). soapsuds.exe
, Remoting.
RemotingConfiguration.Configure,
, ,
. Remoting
-, wsdl.exe
-.
Remoting
IIS, HTTP.
161
8. .NET Remoting
web.config ,
bin .
Remoting ,
IIS.
SSL. SSL,
, https://.
IIS
.
RemoteObject object = new RemoteObject();
//
IDictionary properties = ChannelServices.GetChannelSinkProperties(object);
properties["username"] = username;
properties["password"] = password;
//
object.Do();
IIS
PrincipalPermissionAttribute, ,
,
.
IPrincipal principal = System.Threading.Thread.CurrentPrincipal;
if (!principal.IsInRole(Environment.MachineName + @"\SomeGroup"))
{
throw new UnauthorizedAccessException(" .");
}
Active
Directory IIS ,
.
<channel ref="http" useDefaultCredentials="true" />
8. .NET Remoting
Active Directory Windows
.
8.5.
Remoting
, Remoting ,
, (chain).
, ,
. NextSink (
IMessageSink)
NextChannelSink
IClientChannelSink
IServerChannelSink).
.Net Remoting
8.5.
(sink providers).
IClientChannelSinkProvider
IServerChannelSinkProvider,
163
8. .NET Remoting
CreateSink (. 8.5). , (
IMessageSink)
CreateMessageSink.
, ,
.
ChannelServices.CreateServerChannelSinkChain,
DispatchChannelSinkProvider.
,
, .
, Next.
. , TcpClientChannel (
TcpChannel) BinaryClientFormatterSinkProvider
TcpClientTransportSinkProvider.
.
<channel><serverProviders><formatter>
<channel><clientProviders><formatter> .
binary soap.
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown mode="SingleCall"
type="RemotingTest.TestService, RemoteTestService"
objectUri="endpoint"/>
</service>
<channels>
<channel ref="http" port="2080">
<serverProviders>
<formatter ref="binary"/>
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
164
8. .NET Remoting
.
- .
,
Remoting IIS, VPN
(, OpenVPN).
.NET Remoting.
, ,
.
.
<channel><clientProviders><provider>.
,
.
FCL III.
// SevaRemotingEncrypted.cs
using System;
using System.IO;
using System.Collections;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Messaging;
using Seva.Security.Encryption;
namespace Seva.Remoting.Encryption
{
class EncryptedClientChannelSinkProvider: IClientChannelSinkProvider
{
private IClientChannelSinkProvider next;
public IClientChannelSinkProvider Next
{
get { return next; }
set { next = value; }
}
private SymmetricEncryptor encryptor;
165
8. .NET Remoting
, .
,
.
public EncryptedClientChannelSinkProvider(IDictionary properties,
ICollection providerData)
{
string keyFile = (string) properties["key"];
Console.WriteLine("Client key: [{0}]", keyFile);
encryptor = new SymmetricEncryptor(keyFile);
}
CreateSink .
,
, . ,
, Next
.
public IClientChannelSink CreateSink(IChannelSender channel,
string url, object remoteChannelData)
{
IClientChannelSink next = Next.CreateSink(channel,
url, remoteChannelData);
return new EncryptedClientChannelSink(encryptor, next);
}
}
.
class EncryptedServerChannelSinkProvider : IServerChannelSinkProvider
{
private IServerChannelSinkProvider next;
private SymmetricEncryptor encryptor;
public IServerChannelSinkProvider Next
{
get { return next; }
set { next = value; }
}
public EncryptedServerChannelSinkProvider(IDictionary properties,
ICollection providerData)
{
string keyFile = (string) properties["key"];
Console.WriteLine("Server key: [{0}]", keyFile);
encryptor = new SymmetricEncryptor(keyFile);
}
166
8. .NET Remoting
//
public IServerChannelSink CreateSink(IChannelReceiver channel)
{
IServerChannelSink nextSink = Next.CreateSink(channel);
return new EncryptedServerChannelSink(channel, encryptor, nextSink);
}
//
public void GetChannelData(IChannelDataStore channelData)
{
}
}
.
class EncryptedServerChannelSink : IServerChannelSink
{
public IDictionary Properties
{
get { return null; }
}
private IServerChannelSink nextSink;
public IServerChannelSink NextChannelSink
{
get { return nextSink; }
}
private SymmetricEncryptor encryptor;
public EncryptedServerChannelSink(IChannelReceiver channel,
SymmetricEncryptor channelEncryptor, IServerChannelSink next)
{
encryptor = channelEncryptor;
nextSink = next;
}
ProcessMessage.
, .
.
//
public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack,
IMessage requestMsg, ITransportHeaders requestHeaders,
Stream requestStream, out IMessage responseMsg,
out ITransportHeaders responseHeaders, out Stream responseStream)
{
Stream plainStream = null;
MemoryStream decodedStream = new MemoryStream();
requestStream = Utils.ReadAllStream(requestStream);
167
8. .NET Remoting
//
encryptor.Decrypt(requestStream, decodedStream);
decodedStream.Position = 0;
ServerProcessing result = nextSink.ProcessMessage(sinkStack,
requestMsg, requestHeaders, decodedStream, out responseMsg,
out responseHeaders, out plainStream);
//
responseStream = new MemoryStream();
encryptor.Encrypt(plainStream, responseStream);
responseStream.Position = 0;
//
return result;
}
public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack,
Object state, IMessage msg, ITransportHeaders headers, Stream stream)
{
throw new NotSupportedException();
}
public Stream GetResponseStream(IServerResponseChannelSinkStack sinkStack,
Object state, IMessage msg, ITransportHeaders headers)
{
return nextSink.GetResponseStream(sinkStack, state, msg, headers);
}
} // EncryptedServerChannelSink
.
class EncryptedClientChannelSink: IClientChannelSink
{
public IDictionary Properties
{
get { return null; }
}
private IClientChannelSink nextSink;
public IClientChannelSink NextChannelSink
{
get { return nextSink; }
}
private SymmetricEncryptor encryptor;
public EncryptedClientChannelSink(SymmetricEncryptor channelEncryptor,
IClientChannelSink next)
{
encryptor = channelEncryptor;
nextSink = next;
}
168
8. .NET Remoting
public void ProcessMessage(IMessage message,
ITransportHeaders requestHeaders, Stream requestStream,
out ITransportHeaders responseHeaders, out Stream responseStream)
{
MemoryStream encryptedStream = new MemoryStream();
Stream serverStream = null;
//
encryptor.Encrypt(requestStream, encryptedStream);
encryptedStream.Position = 0;
nextSink.ProcessMessage(message, requestHeaders, encryptedStream,
out responseHeaders, out serverStream);
serverStream = Utils.ReadAllStream(serverStream);
//
responseStream = new MemoryStream();
encryptor.Decrypt(serverStream, responseStream);
responseStream.Position = 0;
}
public Stream GetRequestStream(IMessage msg, ITransportHeaders headers)
{
return null;
}
public void AsyncProcessRequest(IClientChannelSinkStack sinkStack,
IMessage message, ITransportHeaders headers, Stream stream)
{
throw new NotSupportedException();
}
public void AsyncProcessResponse(
IClientResponseChannelSinkStack sinkStack, object state,
ITransportHeaders headers, Stream stream)
{
throw new NotSupportedException();
}
} // EncryptedClientChannelSink
Utils ,
Length.
public static class Utils
{
public static MemoryStream ReadAllStream(Stream input)
{
byte[] buffer = new byte [1024];
MemoryStream output = new MemoryStream();
while (true)
{
int read = input.Read(buffer, 0, buffer.Length);
output.Write(buffer, 0, read);
if (read < buffer.Length) break;
}
output.Position = 0;
return output;
}
}
}
// SevaRemotingEncrypted.cs
169
8. .NET Remoting
make-.
makefile : Client.exe SevaRemotingEncrypted.dll
common = Seva*.cs
Client.exe : Client.cs RemoteService.dll
csc /r:RemoteService.dll Client.cs
RemoteService.dll : RemoteService.cs
csc /t:library RemoteService.cs
SevaRemotingEncrypted.dll: $(common)
csc /out:SevaRemotingEncrypted.dll /t:library $(common)
,
.
.
<configuration>
<system.runtime.remoting>
<application>
<client>
<wellknown
type="RemoteService.RemoteServiceTest, RemoteService"
url="tcp://localhost:10020/endpoint"
/>
</client>
<channels>
<channel ref ="tcp">
<clientProviders>
<formatter ref="binary"/>
<provider type="Seva.Remoting.Encryption.
EncryptedClientChannelSinkProvider, SevaRemotingEncrypted"
key="secret.key"
/>
</clientProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
, .NET Remoting
Remoting, -
.
.
8.6.
Remoting
.
170
8. .NET Remoting
Remoting ,
TCP/IP.
Remoting
MSMQ.
TcpChannel HttpChannel,
.
.
8.6. . ,
MSMQ,
, MSMQ.
IMessage
IMessage
MSMQ
MSMQ
MSMQ
IMessage
System.Runtime.Remoting.Messaging.OneWayAttribute,
.
171
8. .NET Remoting
: c
MsmqChannelSender, IChannelSender,
MsmqChannelReceiver, IChannelReceiver.
MSMQ MsmqClient MsmqServer,
MSMQ.
// SevaRemotingMsmq.cs
using System;
using System.IO;
using System.Collections;
using
using
using
using
using
System.Runtime.Remoting;
System.Runtime.Remoting.Channels;
System.Runtime.Remoting.Messaging;
System.Runtime.Serialization.Formatters.Binary;
System.Messaging;
using System.Text.RegularExpressions;
// MSMQ
// c
using Seva.Msmq;
//
// Remoting / MSMQ
namespace Seva.Remoting.MsmqChannel
{
//
public class MessageProperties
{
public const string Uri
= "__Uri";
public const string ObjectUri
= "__ObjectUri";
}
MsmqBase .
Parse, URL
. URL
msmq://.\Private$\remoting_queue\endpoint
.\Private$\remoting_queue ( , ),
endpoint .
// MsmqSender MsmqReceiver
public class MsmqBase: MarshalByRefObject, IChannel
{
// IChannel
public int ChannelPriority { get { return 1;} }
public string ChannelName { get{ return "msmq";} }
172
8. .NET Remoting
// URL
public string Parse(string url, out string objectUri)
{
return Utils.ParseUrl(url, out objectUri);
}
}
MsmqChannelSender clientSinkProvider
, ,
.
, MSMQ.
Remoting
, ,
.
//
public class MsmqChannelSender: MsmqBase, IChannelSender
{
public MsmqChannelSender(IDictionary properties,
IClientChannelSinkProvider clientSinkProvider)
{
// MSMQ,
//
if (clientSinkProvider!=null)
{
throw new NotSupportedException(
" .");
}
}
CreateMessageSink, IChannelSender,
.
public IMessageSink CreateMessageSink(string url,
object channelData, out string objectUri)
{
// URL
string remoteobjectUrl = Utils.ParseUrl(url, ChannelName,
out objectUri);
if (remoteobjectUrl == null)
return null;
//
return new MsmqClientChannelSink(remoteobjectUrl);
}
} // Seva.Remoting.MsmqChannel.Msmq.MsmqSender
MsmqClientChannelSink
MSMQ.
173
8. .NET Remoting
//
public class MsmqClientChannelSink: IMessageSink
{
// MSMQ, IMessage
// ,
// void
private MsmqClient<IMessage, IMessage> msmqClient;
// MSMQ (endpoint)
private string queuePath = null;
private string objectUri = null;
MSMQ
.
public MsmqClientChannelSink(string remoteObjectUri)
{
// URL
queuePath = Utils.ParseUrl(remoteObjectUri, out objectUri);
// MSMQ,
//
msmqClient = new MsmqClient<IMessage, IMessage>(queuePath, null,
QueueFormatter.Binary);
}
public IMessage SyncProcessMessage(IMessage msg)
{
throw new NotSupportedException(
" OneWayAttribute.");
}
AsyncProcessMessage .
Remoting MSMQ.
public IMessageCtrl AsyncProcessMessage(IMessage message,
IMessageSink replySink)
{
// c
message.Properties[MessageProperties.ObjectUri] = objectUri;
// MSMQ
msmqClient.Send(message);
return null;
}
// -
public IMessageSink NextSink
{
get { return null; }
}
// Seva.Remoting.MsmqChannel.MsmqClientChannelSink
MsmqChannelReceiver.
174
8. .NET Remoting
public class MsmqChannelReceiver: MsmqBase, IChannelReceiver
{
// - MSMQ Remoting
private MsmqServer<IMessage, IMessage> msmqServer;
//
private IServerChannelSink
sink;
//
private ServerChannelSinkStack stack;
//
public object ChannelData
{
get { return null; }
}
MsmqServer,
.
ProcessMessage .
, .
public MsmqChannelReceiver(IDictionary properties,
IServerChannelSinkProvider serverSinkProvider)
{
// MSMQ
msmqServer = new MsmqServer<IMessage, IMessage>(
properties["queue"].ToString(), QueueFormatter.Binary);
msmqServer.ProcessMessage += OnReceive;
if (serverSinkProvider!=null)
{
throw new NotSupportedException(
" .");
}
MsmqReceiver, MsmqServer,
.
sink = ChannelServices.CreateServerChannelSinkChain(null, this);
//
stack = new ServerChannelSinkStack();
stack.Push(sink, null);
//
StartListening(null);
}
// IChannelReceiver, URL URI
public virtual string[] GetUrlsForUri(string objectURI)
{
return new string[] {objectURI};
}
175
8. .NET Remoting
// MSMQ
private IMessage OnReceive(Object sender, IMessage request,
MessageQueue queueResponse)
{
return ProcessMessage(request);
}
// ,
public void StartListening(Object data)
{
msmqServer.BeginReceive();
}
public void StopListening(Object data)
{
msmqServer.EndReceive();
}
Utils URL.
public static class Utils
{
// URL
public static string ParseUrl(string url, string channelName,
out string objectUri)
{
objectUri = null;
Regex re = new Regex(@"^" + channelName + @"\:\/\/(.+)$");
Match m = re.Match(url);
if (!m.Success) return null;
176
8. .NET Remoting
make-
.
makefile : SevaRemotingMsmq.dll
common = SevaRemotingMsmq.cs SevaMsmq.cs
SevaRemotingMsmq.dll: $(common)
csc /out:SevaRemotingMsmq.dll /t:library $(common)
,
, <channel>.
<configuration>
<system.runtime.remoting>
<application>
<client>
<wellknown
type="RemoteService.RemoteServiceOneWay, RemoteService"
url="msmq://.\Private$\remoting_queue\service" />
</client>
<channels>
<channel
type="Seva.Remoting.MsmqChannel.MsmqChannelSender, SevaRemotingMsmq"/>
</channels>
</application>
</system.runtime.remoting>
</configuration>
177
8. .NET Remoting
.
<configuration>
<system.runtime.remoting>
<application name="JobServer">
<service>
<wellknown mode="SingleCall"
type="RemoteService.RemoteServiceOneWay, RemoteService"
objectUri="service" />
</service>
<channels>
<channel
type="Seva.Remoting.MsmqChannel.MsmqChannelReceiver, SevaRemotingMsmq"
queue = ".\Private$\remoting_queue"/>
</channels>
</application>
</system.runtime.remoting>
</configuration>
, .NET Remoting
.
.NET Remoting.
8.7.
.NET Remoting
Remoting
.
, IpChannel.
,
IIS.
.NET Remoting
.
Remoting - ( Remoting-Soap)
( Remoting-Binary).
1. . Remoting-Binary
, CLI,
178
8. .NET Remoting
, .
Remoting-Soap ,
SOAP WSDL.
2. . , .NET Remoting,
, .
.
3. . Remoting
.
4. . Remoting
,
.
5. . Remoting-Soap IIS.
IIS Remoting -
,
VPN. ,
Remoting
).
, MSMQ.
6.
Remoting-Binary
.
Remoting ,
. ,
, ,
.
, , .NET Remoting
. , IIS
179
8. .NET Remoting
Remoting -,
- .NET Remoting WSE.
.NET Remoting IIS
- HTTP , ,
IpcChannel. ,
, IIS ,
.NET Remoting. Remoting
LAN TCP ,
.
.NET Remoting
CLI.
180
9. .NET Framework
9.
.NET Framework
,
, .NET Framework.
9.1.
,
(. 9.1).
,
:
OSI (, TCP).
, ,
.
9.1.
181
9. .NET Framework
,
:
();
(
);
().
,
.
- .
- ASP.NET.
:
( WSE);
HTTPS;
IP (IPSec), -
TCP, HTTP.
.NET
Remoting.
, HTTP
HTTPS IIS, MSMQ , IPSec.
Remoting ,
.
.
1. . ,
, .
2. .
-
.
182
9. .NET Framework
3. .
(, -)
.
4.
,
.
.
1. .
.
.
2. .
, .
.
,
.
, ,
.
,
.
9.2.
X.509.
PKI
,
.
183
9. .NET Framework
,
(. 9.2).
9.2.
X.509,
, (,
) .
(certificate authority, CA).
,
- MD5, CA.
(. 9.3).
, :
,
.
,
. .
184
9. .NET Framework
(CA)
9.3.
,
PKI (,
Windows Certificate Services).
,
.
.
,
.
:
, ;
, .
185
9. .NET Framework
.
,
, .NET
Framework:
SSL;
IPsec;
HTTPS;
- WS-Security;
MSMQ.
,
,
.
Kerberos
Kerberos
.
Microsoft Windows 2000 .
Kerberos ,
(key distribution center, KDC).
Active Directory
(ticket-granting ticket, TGT),
Kerberos .
KDC,
(service ticket),
, ,
, .
.
,
(authenticator),
186
9. .NET Framework
. .
, .
.
Kerberos Microsoft Windows :
IPSec/IKE;
- WS-Security.
.NET Framework
MSMQ LAN;
Remoting IIS, ;
Remoting IIS.
9.1
. VPN
SSL IPSec.
,
Remoting,
.
187
9. .NET Framework
9.1. .NET Framework
MSMQ
MSMQ / HTTP
ES / COM+
WS
Remoting
Remoting / IIS
VPN, WIS
X.509
WIS, VPN
(WIS)
VPN
VPN
LAN
Remoting
Active Directory
LAN/VPN
MSMQ
COM+
MSMQ/HTTP
WS
Remoting / IIS
9.4.
. 9.4
.
, ,
,
. ,
188
9. .NET Framework
- ,
, .
9.4.
- WSE
, -
. MSMQ COM+
. Remoting
IIS / MSMQ, ,
.
189
10.
10.
.
10.1.
.NET Framework
. . 10.1 (
Remoting / MSMQ). RPC . 10.1
Windows NT 5.* ,
.
.
WS
Remoting
MSMQ
MSMQ
MSMQ
COM+
IIS
HTTP
RPC
TCP
UDP
IP
10.1.
190
10.
10.2.
. COM+
(JIT-activation). .NET
Remoting :
,
:
WAN ;
VPN
.
10.1.
MSMQ
AD
COM+ (JIT)
AD
Remoting/HTTP/SOAP/IIS
WAN
Remoting/TCP
VPN
Remoting, .
VPN
WAN
WS
191
10.
.
1. - .
2. MSMQ (
), ( Microsoft)
.
3. Remoting :
,
,
CLI.
10.1 ,
.NET .NET Remoting.
,
, .
.
1. .Net Remoting
,
IIS. IIS Remoting
, WSE
-.
2.
MSMQ
Active Directory
Remoting COM+. MSMQ IIS
.
3. Enterprise Services / COM+
, ,
. ,
.
192
10.
,
.
4. - ASP.NET / WSE
. - ASP.NET
,
COM+.
.
. 10.2
,
, .
- (ASP.NET Remoting),
MSMQ HTTP.
MSMQ
MSMQ
WS
MSMQ
HTTP
MSMQ
COM+
MSMQ COM+
-
ASP.NET
WS
COM+
WS
-
Remoting
Remoting
WS
Remoting
10.2.
193
10.
10.3.
.NET Framework
.NET
Framework
2.0
,
.
(, WS COM+),
,
.
Remoting
.
.NET Framework , ,
,
.
194
1.
., . . .
. : . 2003 . 880 c.
2.
3.
4.
5.
: Microsoft
Microsoft Developer Network (MSDN),
http://msdn.microsoft.com.
195
I. COM+
I. COM+
.NET Framework 2.0
COM+,
COM+ regsvcs.exe. ,
.NET Framework
COM+. .
COM
COM+,
.NET
%systemroot%\system32\com\comadmin.dll.
.
sn /k comadmin.snk
tlbimp %Systemroot%\system32\com\comadmin.dll /keyfile:comadmin.snk
/out:interop.comadmin.dll /namespace:ComAdmin
COM-
CLR
interop.comadmin.dll,
ComAdmin.
interop.comadmin
COM+.
COM+, .
I.I COM+,
.
196
I. COM+
COM+
COM+
(Applications)
COM+
DCOM
(Components)
(InterfacesForComponents)
(MethodsForInterface)
c
COM+
(Roles)
(SubscriptionsForComponent)
(RolesForComponent)
(RolesForInterface)
(RolesForMethod)
I.I. COM+
LceUtils
. .
// SevaComLCE.cs
using System;
using ComAdmin;
namespace Seva.ComUtils
{
public static class LceUtils
{
//
public static void PermanentSubscription(string appName,
string subscriberName, string eventGuid, string interfaceGuid)
{
// COM+
COMAdminCatalog catalog = new ComAdmin.COMAdminCatalogClass();
ICatalogObject CatalogObject = null;
ICatalogCollection CompCollection = null, SubCollection = null;
// COM+
ICatalogCollection AppCollection = (ICatalogCollection)
catalog.GetCollection("Applications");
AppCollection.Populate();
197
I. COM+
//
for (int Counter = 0; Counter < AppCollection.Count; Counter++)
{
CatalogObject = (ICatalogObject) AppCollection.get_Item(Counter);
if ((String)CatalogObject.Name == appName)
{
//
CompCollection = (ICatalogCollection)
AppCollection.GetCollection("Components",
CatalogObject.Key);
CompCollection.Populate();
break;
}
}
if (CompCollection == null)
{
throw new ApplicationException(
String.Format("COM+ Application not found : [{0}]", appName));
}
//
for (int Counter = 0; Counter < CompCollection.Count; Counter++)
{
CatalogObject = (ICatalogObject) CompCollection.get_Item(Counter);
if ((String)CatalogObject.Name == subscriberName)
{
//
SubCollection = (ICatalogCollection)
CompCollection.GetCollection(
"SubscriptionsForComponent", CatalogObject.Key);
SubCollection.Populate();
break;
}
}
if (SubCollection == null)
{
throw new ApplicationException(
String.Format("Component not found : [{0}]", subscriberName));
}
//
CatalogObject = (ICatalogObject)SubCollection.Add();
CatalogObject.set_Value("EventCLSID", "{" + eventGuid + "}");
CatalogObject.set_Value("Name", "Permanent Subscription");
CatalogObject.set_Value("InterfaceID", "{" + interfaceGuid + "}");
CatalogObject.set_Value("Enabled", true);
//
SubCollection.SaveChanges();
} // Subscribe
} //LceUtils
} // Seva.ComUtils
198
199
200
201
202
ASP- www
8080.
// AspServer.cs
using System;
using System.IO;
using Seva.AspHost;
class Program
{
static void Main(string[] args)
{
string[] prefixes = new string[]
{
"http://localhost:8080/", "http://127.0.0.1:8080/"
};
AspHost host = AspHost.CreateHost(prefixes, "/",
Directory.GetCurrentDirectory()+@"\www");
host.Start();
foreach (string s in prefixes)
Console.WriteLine(s);
while (true)
host.ProcessRequest();
}
}
ApplicationHost.CreateApplicationHost (
AspHost) , , .
make- ASP.NET.
all: ASPServer.exe
ASPServer.exe: *.cs AspHost.dll
csc /out:ASPServer.exe AspServer*.cs /r:AspHost.dll
AspHost.dll: SevaAspHost.cs AspHost.key
csc /out:ASPHost.dll /t:library SevaAspHost.cs /keyfile:AspHost.key
AspHost.key:
sn -k AspHost.key
install:
gacutil -i ASPHost.dll
if not exist www md www
III.
III.
, .NET Remoting,
.
FCL RijndaelManaged,
.
,
. Encrypt Decrypt
.
// SevaSecurityCipher.cs
using System;
using System.IO;
using System.Security.Cryptography;
namespace Seva.Security.Encryption
{
public class SymmetricEncryptor
{
public const int KeySize = 32;
public const int BlockSize = 32;
RijndaelManaged cipher = null;
public byte[] Key
{
get { return cipher.Key; }
set { cipher.Key = value; }
}
public SymmetricEncryptor()
{
cipher = CreateCipher();
cipher.GenerateKey();
}
public SymmetricEncryptor(byte[] key)
{
cipher = CreateCipher();
cipher.Key = key;
}
204
III.
public void SaveKey(string fileName)
{
using (FileStream file = new FileStream(fileName,
FileMode.Create, FileAccess.Write))
{
file.Write(Key, 0, Key.Length);
}
}
public void LoadKey(string fileName)
{
byte[] buffer = new byte[KeySize];
using (FileStream file = new FileStream(fileName,
FileMode.Open, FileAccess.Read))
{
file.Read(buffer, 0, KeySize);
}
Key = buffer;
}
public byte[] CreateEmptyIv()
{
return new byte[SymmetricEncryptor.BlockSize];
}
public byte[] EncryptMessage(byte[] plainText, out byte[] iv)
{
cipher.GenerateIV();
iv = cipher.IV;
ICryptoTransform transform = cipher.CreateEncryptor();
byte[] cipherText = transform.TransformFinalBlock(plainText,
0, plainText.Length);
return cipherText;
}
public byte[] DecryptMessage(byte[] cipherText, byte[] iv)
{
cipher.IV = iv;
ICryptoTransform transform = cipher.CreateDecryptor();
byte[] plainText = transform.TransformFinalBlock(cipherText,
0, cipherText.Length);
return plainText;
}
public void Encrypt(Stream input, Stream output)
{
byte[] iv = null;
byte[] buffer = new byte[input.Length];
input.Read(buffer, 0, buffer.Length);
buffer = EncryptMessage(buffer, out iv);
//
output.Write(iv, 0, iv.Length);
output.Write(buffer, 0, buffer.Length);
}
205
III.
public void Decrypt(Stream input, Stream output)
{
byte[] iv = CreateEmptyIv();
byte[] buffer = new byte[input.Length-iv.Length];
input.Read(iv, 0, iv.Length);
input.Read(buffer, 0, buffer.Length);
//
buffer = DecryptMessage(buffer, iv);
output.Write(buffer, 0, buffer.Length);
}
private RijndaelManaged CreateCipher()
{
RijndaelManaged cipher = new RijndaelManaged();
cipher.KeySize
cipher.BlockSize
cipher.Mode
cipher.Padding
=
=
=
=
KeySize * 8;
BlockSize * 8;
CipherMode.CBC;
PaddingMode.PKCS7;
return cipher;
}
}
}
// SevaSecurityCipher.cs
,
.
// makekey.cs
using System;
using System.IO;
using Seva.Security.Encryption;
class MainApp
{
public static void Main(string[] Args)
{
if (Args.Length != 1)
{
Console.WriteLine("usage: makekey <key_file>");
return;
}
SymmetricEncryptor encryptor = new SymmetricEncryptor();
encryptor.SaveKey(Args[0]);
}
}
// makekey.cs
.
csc MakeKey.cs SevaSecurityCipher.cs
206