概要
SOAP通信の拡張を行うことで、SOAPの圧縮等が可能となります。
以下のコードは圧縮を実装したコードになります。
クライアントRequestを圧縮します。
Responseを解凍します。
コード
Client.vb
Imports System.IO.Compression
Imports System.Web.Services.Protocols
Public Class CompressSoapExtension
Inherits SoapExtension
Private oldStream As Stream
Private newStream As Stream
Public Overrides Function ChainStream(ByVal stream As Stream) As Stream
'oldStreamは通信に使うためのストリーム
oldStream = stream
'newStreamはクライアント内でデータを処理するためのストリーム
newStream = New MemoryStream()
Return newStream
End Function
Public Overloads Overrides Function GetInitializer(ByVal methodInfo As LogicalMethodInfo, _
ByVal attribute As SoapExtensionAttribute) As Object
Return Nothing
End Function
Public Overloads Overrides Function GetInitializer(ByVal webserviceType As Type) As Object
Return Nothing
End Function
Public Overrides Sub Initialize(ByVal initializer As Object)
End Sub
Public Overrides Sub ProcessMessage(ByVal message As SoapMessage)
Select Case message.Stage
Case SoapMessageStage.BeforeSerialize
Case SoapMessageStage.AfterSerialize
'シリアライズ後の処理・データの圧縮を行う
newStream.Position = 0
Dim compressedStream As MemoryStream = Compress(newStream)
'圧縮されたデータをoldStreamに書き込む
compressedStream.Position = 0
Dim readByte As Integer = compressedStream.ReadByte()
While readByte > -1
oldStream.WriteByte(readByte)
oldStream.Flush()
readByte = compressedStream.ReadByte()
End While
oldStream.Flush()
Case SoapMessageStage.BeforeDeserialize
'デシリアライズの前処理・データの解凍を行う
Dim DecompressedStream As MemoryStream = Decompress(oldStream)
DecompressedStream.Position = 0
Dim reader As StreamReader = New StreamReader(DecompressedStream)
Dim rpcMessage As String = reader.ReadToEnd()
'解凍されたデータをnewStreamに書き込む
Dim writer As StreamWriter = New StreamWriter(newStream)
writer.Write(rpcMessage)
writer.Flush()
newStream.Position = 0
End Select
End Sub
Protected Function Compress(ByVal outputStream As Stream) As MemoryStream
'圧縮処理を実装する
Dim num As Integer
Dim buff(1024) As Byte
Dim memStream As New MemoryStream
'' GZipStreamのインスタンスを作成(出力先:memStream、閉じたときにmemStreamを閉じない)
Dim CompStream As New GZipStream(memStream, CompressionMode.Compress, True)
Do
'1kbずつ圧縮する
num = outputStream.Read(buff, 0, buff.Length)
If num <= 0 Then Exit Do
CompStream.Write(buff, 0, num)
Loop
CompStream.Flush()
CompStream.Close()
memStream.Position = 0
Return memStream
End Function
Protected Function Decompress(ByVal inputStream As Stream) As MemoryStream
'解凍処理を実装する
Dim num As Integer
Dim buff(1024) As Byte
Dim memStream As New MemoryStream
Dim CompStream As New GZipStream(inputStream, CompressionMode.Decompress)
Do
''1kbずつ解凍する
num = CompStream.Read(buff, 0, buff.Length)
If num <= 0 Then Exit Do
memStream.Write(buff, 0, num)
Loop
CompStream.Close()
memStream.Position = 0
Return memStream
End Function
End Class
サーバーでRequestを解凍します。
Reqponseを圧縮します。
Server.vb
Public Class CompressSoapExtension
Inherits SoapExtension
Private oldStream As Stream
Private newStream As Stream
Public Overrides Function ChainStream(ByVal stream As Stream) As Stream
'oldStreamは通信に使うためのストリーム
oldStream = stream
'newStreamはクライアント内でデータを処理するためのストリーム
newStream = New MemoryStream()
Return newStream
End Function
Public Overloads Overrides Function GetInitializer(ByVal methodInfo As LogicalMethodInfo, _
ByVal attribute As SoapExtensionAttribute) As Object
Return Nothing
End Function
Public Overloads Overrides Function GetInitializer(ByVal webserviceType As Type) As Object
Return Nothing
End Function
Public Overrides Sub Initialize(ByVal initializer As Object)
End Sub
Public Overrides Sub ProcessMessage(ByVal message As SoapMessage)
Select Case message.Stage
Case SoapMessageStage.BeforeSerialize
'message.ContentEncoding = "gzip"
Case SoapMessageStage.AfterSerialize
'シリアライズ後の処理・データの圧縮を行う
newStream.Position = 0
Dim compressedStream As MemoryStream = Compress(newStream)
'圧縮されたデータをoldStreamに書き込む
compressedStream.Position = 0
Dim readByte As Integer = compressedStream.ReadByte()
While readByte > -1
oldStream.WriteByte(readByte)
oldStream.Flush()
readByte = compressedStream.ReadByte()
End While
oldStream.Flush()
Case SoapMessageStage.BeforeDeserialize
'デシリアライズの前処理・データの解凍を行う
oldStream.Position = 0
Dim DecompressedStream As MemoryStream = Decompress(oldStream)
DecompressedStream.Position = 0
Dim reader As StreamReader = New StreamReader(DecompressedStream)
Dim rpcMessage As String = reader.ReadToEnd()
'解凍されたデータをnewStreamに書き込む
Dim writer As StreamWriter = New StreamWriter(newStream)
writer.Write(rpcMessage)
writer.Flush()
newStream.Position = 0
End Select
End Sub
Protected Function Compress(ByVal outputStream As Stream) As MemoryStream
'圧縮処理を実装する
Dim num As Integer
Dim buff(1024) As Byte
Dim memStream As New MemoryStream
Dim CompStream As New GZipStream(memStream, CompressionMode.Compress, True)
Do
num = outputStream.Read(buff, 0, buff.Length)
If num <= 0 Then Exit Do
CompStream.Write(buff, 0, num)
Loop
CompStream.Flush()
CompStream.Close()
memStream.Position = 0
Return memStream
End Function
Protected Function Decompress(ByVal inputStream As Stream) As MemoryStream
'解凍処理を実装する
Dim num As Integer
Dim buff(1024) As Byte
Dim memStream As New MemoryStream
Dim CompStream As New GZipStream(inputStream, CompressionMode.Decompress)
Do
num = CompStream.Read(buff, 0, buff.Length)
If num <= 0 Then Exit Do
memStream.Write(buff, 0, num)
Loop
CompStream.Close()
memStream.Position = 0
Return memStream
End Function
End Class