diff --git a/udsp/ask.js b/udsp/ask.js index 130c5ea8..2c5fce5c 100644 --- a/udsp/ask.js +++ b/udsp/ask.js @@ -11,66 +11,35 @@ import { decode, encode } from 'msgpackr'; import { failed, info, msgReceived, msgSent } from '#logs'; -import { assembleData } from './request/assembleData.js'; import { Base } from './request/base.js'; -import { bufferPacketization } from './request/bufferPacketization.js'; -import { request } from '#udsp/request'; export class Ask extends Base { - constructor(config, source) { - super(config, source); - const { - message, - options, - } = config; + constructor(requestObject, options = {}, source) { + super(options, source); const { queue, packetIdGenerator, - maxPacketSize + maxPacketSize, } = source; - assign(this.request, message); - // sid is a Stream ID + const { + data, + head, + method + } = requestObject; + console.log('Ask', requestObject); const streamId = packetIdGenerator.get(); this.request.sid = streamId; this.packetTemplate.sid = streamId; this.id = streamId; - queue.set(streamId, this); - } - async assemble() { - const { contentType } = this; - if (this.data) { - this.data = await assembleData(this.data, this.response, contentType); - console.log('Assembled', this.data); - } - this.destroy(); - await this.accept(this); - } - async send(data) { - const thisAsk = this; - const { - packetTemplate, - contentType, - maxPacketSize, - sid - } = this; if (data) { this.request.data = data; } - console.log('Reply.send', this.response); - if (this.request.data) { - if (!isBuffer(this.request.data)) { - this.request.data = this.dataToBuffer(this.request.data); - } - this.totalReplyDataSize = request.data?.length; + if (head) { + this.request.head = head; } - if (this.contentType) { - this.request.head.contentType = this.contentType; + if (method) { + this.request.method = method; } - await bufferPacketization(this.request.data, sid, this.outgoingPackets, maxPacketSize, contentType); - const awaitingResult = promise((accept) => { - thisAsk.accept = accept; - }); - thisAsk.sendAll(); - return awaitingResult; + queue.set(streamId, this); } isAsk = true; type = 'ask'; diff --git a/udsp/base.js b/udsp/base.js new file mode 100644 index 00000000..f492f218 --- /dev/null +++ b/udsp/base.js @@ -0,0 +1,27 @@ +import { construct, UniqID } from '@universalweb/acid'; +import { actions } from './server/actions/index.js'; +class UDSP { + constructor() { + return this.initialize(); + } + async initialize() { + } + gracePeriod = 30000; + maxPacketSize = 1328; + connectionIdSize = 8; + actions = construct(Map); + stateCodeDescriptions = ['initializing', 'initialized', 'failed to initialize']; + state = 0; + /* + * A puzzle used to challenge clients to ensure authenticity, connection liveliness, and congestion control. + * Slow down account creation. + * Generate crypto currency or compute work. + */ + puzzleFlag = false; + /* + * IPv6 preferred. + */ + ipVersion = 'udp6'; + events = construct(Map); + streamIdGenerator = construct(UniqID); +} diff --git a/udsp/client/connect.js b/udsp/client/connect.js index d09e43c3..87bb4b3e 100644 --- a/udsp/client/connect.js +++ b/udsp/client/connect.js @@ -5,15 +5,18 @@ export async function connect(message = {}) { const thisClient = this; // opn stands for open meaning connect to a server message.intro = 'Hello Server!'; - const result = await thisClient.fetch('opn', message); - console.log('Connect response', result.response.data); + const connectRequest = thisClient.request({ + message + }, 'connect'); + console.log('Connect request', connectRequest); + const connectResponse = await connectRequest.send(); const { data, state, time, // server connection ID sid - } = result; + } = connectResponse; if (state === 1 && sid) { connected(data); thisClient.state = 1; @@ -27,5 +30,5 @@ export async function connect(message = {}) { } } console.log('-------CLIENT CONNECTED-------\n'); - return result; + return connectResponse; } diff --git a/udsp/client/index.js b/udsp/client/index.js index ba8483cc..08e5e64f 100644 --- a/udsp/client/index.js +++ b/udsp/client/index.js @@ -175,8 +175,8 @@ export class Client { this.socket.close(); Client.connections.delete(this.id); } - ask(message) { - const ask = construct(Ask, [message, this]); + ask(message, options) { + const ask = construct(Ask, [message, options, this]); return ask; } connect = clientConnect; diff --git a/udsp/request.js b/udsp/request.js index 56027975..ea2f4574 100644 --- a/udsp/request.js +++ b/udsp/request.js @@ -3,15 +3,16 @@ import { } from '#logs'; import { promise, construct, isString } from '@universalweb/acid'; imported('Request'); -export async function request(source, options) { - if (options) { - if (isString(options)) { - source.method = options; - } - source.method = options.method; +export function request(data, options) { + let target = data; + if (isString(options)) { + target = { + method: options, + data + }; } - info(`Request Function: ${source.method}`); - const ask = this.ask(source, options); - console.log(ask); + info(`Request Function: ${target.method}`); + const ask = this.ask(target, options); + console.log(target, ask); return ask; } diff --git a/udsp/request/base.js b/udsp/request/base.js index b3f00ae6..81c19a8d 100644 --- a/udsp/request/base.js +++ b/udsp/request/base.js @@ -7,22 +7,21 @@ import { flushOutgoing, flushIncoming, flush } from './flush.js'; import { sendPacketsById } from './sendPacketsById.js'; import { sendAll } from './sendAll.js'; import { onPacket } from './onPacket.js'; -import { isBuffer, isPlainObject, isString } from '@universalweb/acid'; +import { + isBuffer, isPlainObject, isString, promise, assign +} from '@universalweb/acid'; import { encode } from 'msgpackr'; import { request } from '#udsp/request'; +import { assembleData } from './assembleData.js'; export class Base { - constructor(config, source) { - const { events } = config; + constructor(options = {}, source) { + const { events, } = options; const timeStamp = Date.now(); this.created = timeStamp; this.source = function() { return source; }; - const { - queue, - packetIdGenerator, - maxPacketSize - } = source; + const { maxPacketSize } = source; if (events) { this.on(events); } @@ -31,27 +30,23 @@ export class Base { } } code(codeNumber) { + const source = (this.isAsk) ? this.request : this.response; if (this.isAsk) { - this.request.head.code = codeNumber; + source.head.code = codeNumber; } else { - this.response.head.code = codeNumber; + source.head.code = codeNumber; } } - setHeader(headerName, headerValue) { - if (this.isAsk) { - if (!this.request.head) { - this.request.head = {}; - } - this.request.head[headerName] = headerValue; - } + setHeader(target) { + const source = (this.isAsk) ? this.request : this.response; + assign(source.head, target); } writeHeader(headerName, headerValue) { - if (this.isReply) { - if (!this.response.head) { - this.response.head = {}; - } - this.response.head[headerName] = headerValue; + const source = (this.isAsk) ? this.request : this.response; + if (!source.head) { + source.head = {}; } + source.head[headerName] = headerValue; } dataToBuffer(data) { if (isBuffer(data)) { @@ -63,6 +58,44 @@ export class Base { } return Buffer.from(data); } + async assemble() { + const { contentType } = this; + if (this.data) { + this.data = await assembleData(this.data, this.response, contentType); + console.log('Assembled', this.data); + } + this.destroy(); + await this.accept(this); + } + async send() { + const thisSource = this; + const { + packetTemplate, + contentType, + maxPacketSize, + sid, + isAsk, + isReply + } = this; + const message = (isAsk) ? this.request : this.response; + console.log(`${this.type}.send`, message); + if (message.data) { + if (!isBuffer(message.data)) { + message.data = this.dataToBuffer(message.data); + } + this.totalReplyDataSize = request.data?.length; + } + if (this.contentType) { + message.head.contentType = this.contentType; + } + // await bufferPacketization(this); + const awaitingResult = promise((accept) => { + thisSource.accept = accept; + }); + console.log(`BASE ${this.type}`, this); + this.sendAll(); + return awaitingResult; + } destroy = destroy; sendEnd = sendEnd; sendPacketsById = sendPacketsById; diff --git a/udsp/request/bufferPacketization.js b/udsp/request/bufferPacketization.js index 151d21ef..ab5e1278 100644 --- a/udsp/request/bufferPacketization.js +++ b/udsp/request/bufferPacketization.js @@ -1,28 +1,44 @@ import { assign } from '@universalweb/acid'; -export async function bufferPacketization(data, sid, packets = [], maxPacketSize, contentType) { - const totalPayloadSize = data?.length; +import { buildMessage } from './buildMessage.js'; +import { request } from '#udsp/request'; +export async function bufferPacketization(source) { + const { + maxPacketSize, + contentType, + method, + id: sid, + isAsk, + outgoingPackets + } = source; + const message = (isAsk) ? this.request : this.response; + const data = message.data; + const dataSize = data?.length; let currentBytePosition = 0; let packetId = 0; - if (totalPayloadSize > maxPacketSize) { + if (dataSize > maxPacketSize) { console.log('Body size', data.length); - while (currentBytePosition < totalPayloadSize) { + while (currentBytePosition < dataSize) { const endIndex = currentBytePosition + maxPacketSize; - const safeEndIndex = endIndex > totalPayloadSize ? totalPayloadSize : endIndex; + const safeEndIndex = endIndex > dataSize ? dataSize : endIndex; const chunk = data.subarray(currentBytePosition, safeEndIndex); console.log('chunksize', chunk.length, currentBytePosition, endIndex); - const packet = assign({ + const packet = { pid: packetId, - sid - }); + endIndex: safeEndIndex, + sid, + head: {} + }; if (packetId === 0) { - if (contentType) { - packet.de = contentType; - } - packet.tps = totalPayloadSize; + buildMessage({ + method, + contentType, + dataSize, + packet + }); } packet.data = chunk; - packets[packetId] = packets; - if (endIndex >= totalPayloadSize) { + outgoingPackets[packetId] = outgoingPackets; + if (endIndex >= dataSize) { packet.end = true; break; } @@ -32,13 +48,17 @@ export async function bufferPacketization(data, sid, packets = [], maxPacketSize } else { const packet = { pid: 0, - end: true + end: true, + data }; - if (contentType) { - packet.de = contentType; - } - packets[0] = packet; + buildMessage({ + method, + contentType, + dataSize, + packet + }); + console.log(source); + outgoingPackets[0] = packet; } - console.log('bufferToPackets', packets); - return packets; + console.log('bufferToPackets', outgoingPackets); } diff --git a/udsp/request/buildMessage.js b/udsp/request/buildMessage.js new file mode 100644 index 00000000..9e94ac60 --- /dev/null +++ b/udsp/request/buildMessage.js @@ -0,0 +1,16 @@ +export function buildMessage({ + method, + contentType, + dataSize, + packet +}) { + if (contentType) { + packet.head.contentType = contentType; + } + if (dataSize) { + packet.head.dataSize = dataSize; + } + if (method) { + packet.method = method; + } +} diff --git a/udsp/request/sendAll.js b/udsp/request/sendAll.js index caf840a1..b4fc3507 100644 --- a/udsp/request/sendAll.js +++ b/udsp/request/sendAll.js @@ -1,7 +1,7 @@ import { eachArray } from '@universalweb/acid'; export async function sendAll() { const thisReply = this; - console.log('outgoingPackets', thisReply.outgoingPackets.length); + console.log('outgoingPackets', thisReply.outgoingPackets); eachArray(thisReply.outgoingPackets, (packet) => { thisReply.sendPacket({ message: packet